How does COM select how to marshal an interface?

后端 未结 2 624
死守一世寂寞
死守一世寂寞 2020-12-29 14:57

As I get it there\'re three ways to implement marshalling in COM:

  • typelib marshalling
  • proxy/stub marshalling
  • implementing IMarshal by the obj
2条回答
  •  情话喂你
    2020-12-29 15:36

    I am a bit rusty at this, but do you have a function named blindquery in your project ? (its usually declared by the wizard if you created a C++ ATL project). Breakpoint inside the function. The function is generated by the wizard often has problems with queryinterface returning E_NOINTERFACE due to buggy code.

    edit (found sample code) from my old project _blindquery

    class ATL_NO_VTABLE CChildEvents :
        public CComObjectRootEx ,
        public CComCoClass,
        public IDispatchImpl
    {
    public:
        CChildEvents(void) :
        m_pItfMgr(0)
        {
        }
    
        /* called from internalQI to tear off a new blind interface */
        static HRESULT WINAPI   _BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD dw);
    
        DECLARE_REGISTRY_RESOURCEID(IDR_CHILDEVENTS)
        DECLARE_PROTECT_FINAL_CONSTRUCT()
    
        BEGIN_COM_MAP(CChildEvents)
            COM_INTERFACE_ENTRY(IChildEvents)
            COM_INTERFACE_ENTRY(IDispatch)
            COM_INTERFACE_ENTRY_FUNC_BLIND(0, _BlindQuery)
        END_COM_MAP()
    };
    
    
    HRESULT WINAPI CChildEvents::_BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD /* dw */ )
    {
        HRESULT hr = E_NOINTERFACE;
        USES_CONVERSION;
    
        try
        {
            if(pvThis == NULL)
            {
                ATLASSERT(FALSE);
            }
            else
            {
                /*
                * cast the pvThis pointer to the actual class £
                * so we can use it here £
                * reinterpret_cast should be safe since we're calling ourself
                */
                CChildEvents    *pThis = reinterpret_cast < CChildEvents * > (pvThis);
                if(pThis == NULL)
                {
                    ATLASSERT(FALSE);
                }
                else
                {
    
                        /* check to see if it matches on of our children's DIID */
                                        if(memcmp(&riid,&l_someotherguid,sizeof(GUID)) == 0) {
    
                            /* if so cast to a IDispatch -- the standard for event interfaces */
                            *ppv = reinterpret_cast < IDispatch * > (pvThis);
    
                            /* addref */
                            pThis->AddRef();
    
                            /* reply */
                            hr = S_OK;
    
                    }
                }
            }
        }
        catch(...)
        {
            ATLASSERT(FALSE);
        }
    
        /* must not be in our map - tell them to GO FISH */
        return(hr);
    }
    

提交回复
热议问题