none
Cannot marshal from C# IReflect object to C++ IDispatch RRS feed

  • Question

  • HI,

    I am struggling with a problem for some time and I hope I can get some guidance here on the community forums.
    The problem is simple:

    I have a com interface:

        [ComImport]
        [Guid("08D7DC4F-40A7-432D-A219-FE5470671DC3")]
        [TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
        public interface IDispatchSupplier
        {
            [MethodImpl(MethodImplOptions.InternalCall)]
            [DispId(1610743809)]
            [return: MarshalAs(UnmanagedType.IDispatch)]
            object GetMyObject([In] [MarshalAs(UnmanagedType.BStr)] string className);
        }

    and implemenation of IDispatchSupplier:

        [ComVisible(true)]
        [ProgId("Test.MyDispatchSupplier")]
        public sealed class DispatchSupplier: IDispatchSupplier
        {
            public object GetMyObject(string className)
            {
                MyReflectObject reflectObject = new MyReflectObject ();
                return reflectObject ;
            }
        }


    and a class that implements IReflect:

        [ComVisible(true), ClassInterface(ClassInterfaceType.None)]
        public sealed class MyReflectObject : IReflect
        {
    
              public MemberInfo[] GetMembers(BindingFlags bindingAttr)
            {
                return _membersArray;
            }
    
           //.......and so on, IReflect is implemented
    
    }

    From C++ I just want to access the ITypeInfoMembers and expecting to have members from IReflect but they are not there

    CComPtr<IDispatchSupplier> dispatchSupplier;
    if (SUCCEEDED(dispatchSupplier.CoCreateInstance(L"Test.MyDispatchSupplier")))
    {
        CComPtr<IDispatch> myDispatchObject;
        HRESULT hr = dispatchSupplier->GetMyObject(micClass, &myDispatchObject);
        if (SUCCEEDED(hr))
        {
            CComPtr<ITypeInfo> myDispatchObjectTypeInfo;
            if (SUCCEEDED(myDispatchObject->GetTypeInfo(NULL, NULL, &myDispatchObjectTypeInfo)))
            {
                TYPEATTR* spTypeAttr = nullptr;
                hr = myDispatchObjectTypeInfo->GetTypeAttr(&spTypeAttr);
                //unique_ptr<TYPEATTR> a(spTypeAttr);
                if (SUCCEEDED(hr))
                {
                    WORD funcsCount = spTypeAttr->cFuncs;
                    for (WORD i = 0; i < funcsCount; i++)
                    {
                        FUNCDESC* spfuncdesc = nullptr;
                        UINT temp = i;
                        hr = myDispatchObjectTypeInfo->GetFuncDesc(temp, &spfuncdesc);
                        //unique_ptr<FUNCDESC> b(spfuncdesc);
                        if (SUCCEEDED(hr) && (spfuncdesc))
                        {
                            long invId = spfuncdesc->invkind;
                            // This is the Function Description of the required method.
                            if (invId == INVOKE_FUNC ||
                                invId == INVOKE_PROPERTYPUT ||
                                invId == INVOKE_PROPERTYPUTREF ||
                                invId == INVOKE_PROPERTYGET)
                            {
    
                                // Get parameters names
                                CBSTRVector Names(50);
                                UINT nNames(0);
                                myDispatchObjectTypeInfo->GetNames(spfuncdesc->memid, &Names, 50, &nNames);
                                nNames = __min(nNames, (UINT)spfuncdesc->cParams + 1);
                                if (nNames < 1)
                                    continue;
                                OutputDebugStringW(L"\r\n");
                                OutputDebugStringW(*Names);
                            }
                        }
                    }
                }
            }
        }
    }

    into output I get com members like:

    AddRef

    QueryInterface

    and so on instead of having members from IReflect
    Can you please help me with this?

    Thank you.

    Thursday, January 16, 2020 7:17 PM

All replies

  • Hi Claudiu_D,

    Thank you for posting here.

    To help you find the correct forum to go ask question, I will move the thread to Where is the forum for forum.

    Thank you for your understanding.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Sunday, January 19, 2020 1:17 AM
    Moderator
  • The IReflect implementation you provided is only exposed as an IDispatch implementation when a COM client QIs directly from MyReflectObject and use the returned IDispatch. It does not affect the behavior of the auto dual dispimpl on the DispatchSupplier object. To use your MyReflectObject in C++ you have to give it a CLSID or return it from some COM method. 


    Visual C++ MVP


    Sunday, January 19, 2020 2:50 AM
  • But how about dynamics?

    Wouldn't be possible to have ITypeInfo generated based on a class derived from dynamic object?

    Thank you.

    Friday, January 24, 2020 4:05 PM
  • The COM server is responsible to generate type info, not the COM client. 



    Visual C++ MVP

    Friday, January 24, 2020 6:08 PM