How does COM choose how to marshal the interface?

As I understand it, there are three ways to implement marshalling in COM:

  • typelib marshalling
  • proxy / stub marshalling
  • IMarshal implementation using an object

Now, how does the user (user) of the component choose which one to use? Does it solve on its own and use the preferred method, or does it invoke some built-in function, and does this solve the problem for this?

I am currently experiencing the following: my component implements a custom ICustomInterface interface, which is also implemented by another company component. My component does not have typelib and does not implement IMarshal. The system registry contains the key HKCR \ Interface {uuidof (ICustomInterface)} \ ProxyStubClsid32 with the proxy / stub GUID, which can be tracked in the library provided by this other company.

Now, when my consumer component initializes my component, it calls QueryInterface (), which requests IMarshal from my component, and when E_NOINTERFACE returns, it just does nothing. Why is this - why does not a proxy / stub from another company start?

+6
windows interop com com-interop
source share
2 answers

The COM runtime will use typelib (oleautomation) marshalling if you mark your interface as used by the standard marshaller by adding its CLSID {00020424-0000-0000-C000-000000000046} under HKCR\Interfaces\{iid}\ProxyStubClsid (where {iid} is the GUID of your interface). You will also need to have a registered library for the runtime to retrieve parameter information, and you can use only a specific subset of types. There is still (old) information here and here .

If you want to use your own proxy server created by the MIDL compiler from your IDL, then you will need to change the interface registry entry as the CLSID of this proxy object. This allows a wider range of types to be used, for example. "raw" arrays.

If you support IMarshal , this will be used in preference to any of these mechanisms. This means that you can change your object to aggregate a marker with arbitrary loading (using its implementation of IMarshal ) without changing anything in the registry. This will avoid creating a proxy.

Hope this helps.

+5
source share

I'm a little rusty, but do you have a function called blindquery in your project? (the wizard usually declares it if you created a C ++ ATL project). Breakpoint inside a function. The function is generated by the wizard, often there are problems with returning the request, returning E_NOINTERFACE due to an error code.

edit (find sample code) from my old project _ blindquery

 class ATL_NO_VTABLE CChildEvents : public CComObjectRootEx <CComSingleThreadModel>, public CComCoClass<CChildEvents, &CLSID_ChildEvents>, public IDispatchImpl<IChildEvents, &IID_IChildEvents, &LIBID_XXX> { 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 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); } 
0
source share

All Articles