An exception of type 'System.Runtime.InteropServices.COMException' occured. Interface not registered (Exception from HRESULT: 0x80040155)

0

I am trying to use a COM Object from a different thread and I am getting this error. The same error does not happen in Single threaded model.

What could be the possible reason?

I tried implementing the interfaces with CComMultiThreadModel. Still no luck.

multithreading
com
asked on Stack Overflow Nov 22, 2011 by Venkatesh Kumar

1 Answer

0

You haven't registered proxy/stub objects for your COM object, and so its interface couldn't be marshalled to the thread in question.

You have two choices a) register the proxies. If the interfaces are private to your app you can merge the proxy stubs. If they are not you should create a separate DLL. The ATL wizard can help you generate proxies, so it's likely you already have them and you just didn't install/register them.

Proxies will ensure that calls to your object take place in the same COM apartment that it is registered for. In your case, STA. This also reduces the need for locking - because only one call will be in your code at once. http://msdn.microsoft.com/en-us/library/ms809971.aspx

Of course, you still need to protect against reentrancy because your STA object may be reentered during its out-calls. http://blogs.msdn.com/b/cbrumme/archive/2004/02/02/66219.aspx

The downside of using proxies is that there is a performance cost, both in marshalling and waiting for the STA.

In the classic Win32 model, you should always use the STA for COM objects that encapsulate UI, because HWNDs are always tied to a single thread.

b) Aggregate the Free-threaded marshaller. You will also find an option for this in ATL. The free-threaded marshaller enables your COM objects to be directly called from any apartment in the process. http://msdn.microsoft.com/en-us/library/windows/desktop/ms694500(v=vs.85).aspx

When you use the FTM, calls on your objects are direct vtable calls - no marshalliong involved.

Chosing this option requires you to make your code thread-safe (by applying appropriate locking) because calls may now come in from multiple threads simultaneously.

An additional burden is that FTM objects cannot directly hold onto interface pointers unless it knows for certain that those objects also aggregate the FTM. So when you get an IUnknown from someone else, you need to store it in an appartment neutral format (such as in the Global Interface Table).

For this and other reasons, the FTM is an advanced choice for folks who know what they are doing. But it is also the highest performance option for non-UI code.

Martyn

answered on Stack Overflow Nov 22, 2011 by Martyn Lovell

User contributions licensed under CC BY-SA 3.0