COM Interface Proxy Explained

advanced topics | home

comInterfaceExternalProxyStub

When a COM call is made between incompatible apartments, COM must marshal the call. Typical example includes an STA and an MTA apartments. To marshal the call COM must transfer parameters to the other apartment and make the call. Think of this as a call from one thread to another. Separate stacks, no way to just make the call. In practice, the most common proxy/stub problems for in-process COM servers are for event handling. Most programmers not handling COM events do not need to be concerned with proxy/stub.

To marshal the call COM uses stub and proxy copying the data in between. Generally the creator of the COM object is responsible for providing the stub and the proxy. However, COM provides standard proxies which are capable of marshaling standard interfaces using type library to discover the details about parameters.

One such proxy/stub is PSDispatch {00020420-0000-0000-C000-000000000046} implemented in oleaut32.dll. This proxy is specifically built to help marshal calls through IDispatch. Another well-known proxy is PSOAInterface {00020424-0000-0000-C000-000000000046}. As the name indicates this is a proxy-stub for OLE automation and it supports types defined in OA.

In standard COM registration the proxy/stub information is stored in the Interface entry in registry. For example:

HKEY_CLASSES_ROOT\Interface\{00000266-0000-0010-8000-00AA006D2EA4}\ProxyStubClsid : {00020420-0000-0000-C000-000000000046}

In win32 side-by-side proxy/stub information is in comInterfaceExternalProxyStub. For example:

<comInterfaceExternalProxyStub
   name="RecordsetEvents"
   iid="{00000266-0000-0010-8000-00AA006D2EA4}"
   tlbid="{B691E011-1797-432E-907A-4D8C69339129}"
   proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
   baseInterface="{00000000-0000-0000-C000-000000000046}"/>

Manifest Maker picks up proxy/stub information from COM DLL's self-registration data. This does not cause problems.

.Net COM-visible objects do not register COM information in the registry. Only the assembly and class information is saved in the registry. Manifest Maker does not use self-registration information for .Net. Instead it reads .Net metadata and uses CLR API to extract or generate necessary side-by-side manifest information. However, not all data is specifed explicitly. For example ThreadingModel is not specifed and is known to be always "Both".

.Net normally uses automation proxy-stub. However VB6 is using dispatch interfaces and expects event marshaling with PSDispatch proxy/stub. This means that a standard side-by-side manifest may cause "object does not match target type" errors, access violations or other seemingly cryptic errors.

As of version 4.6 Manifest Maker adds a per-DLL option to choose between PSOAInterface and PSDispatch proxy/stub for CLR COM-visible classes. The default is PSOAInterface. To change to PSDispatch right-click the DLL in the main window and select "Settings" from the context menu. In the property window change the value of "COM Interface Proxy" from "OLE Automation" to "IDispatch-only". Save and rebuild the manifest.

More information

Support Statement for Visual Basic 6.0
Service Pack 6 for Visual Basic 6.0: Run-Time Redistribution Pack (vbrun60sp6.exe)
MS12-060: Description of the security update for Visual Basic 6.0 Service Pack 6: August 14, 2012