Page 1 of 1

Initialising the COM environment - multi-threaded apartment

Posted: Sat Mar 21, 2009 9:37 pm
by srod
Hi,

I have just discovered that certain PB commands (e.g. MessageRequester()) initialise the COM environment to what I presume is a single-threaded apartment model.

This is fine, except that, well, there are occasions where a multi-threaded apartment model is required (please see page 36 of the COMate thread).

Can I ask, therefore, that you perhaps consider initialising the COM environment (when called for) to a multi-threaded apartment model when the compiler threadsafe switch is set. It would save us having to use CoUninitialize_() etc. just to remove the PB setting, something which I feel is a bit hit and miss! :)

Thanks.

Posted: Sat Mar 21, 2009 10:42 pm
by freak
Sorry, we are pretty much stuck on the single-threaded apartment model for various reasons:

OLE is not threadsafe and therefore only supports the STA. If we use the MTA in CoInitializeEx(), all PB functions which rely on OLE will fail. (Drag & Drop, Clipboard and some others).
See remarks here:
http://msdn.microsoft.com/en-us/library/ms695279.aspx

Also, most of the Shell related functions and other COM related functions that have something to do with user interfaces pretty much require the single threaded apartment to work. Using the MTA would mess up a ton of things there.
See here:
http://support.microsoft.com/kb/287087
http://blogs.msdn.com/oldnewthing/archi ... 01378.aspx

Btw, single threaded apartment does not mean that threads cannot be used. It only means that interface calls across threads are not possible. So automatically switching to the MTA with the threadsafe setting is not needed as the STA works well with thread. Just not for cross-thread object calls.

You may want to look at the CoMarshalInterThreadInterfaceInStream() and CoGetInterfaceAndReleaseStream() functions (killer function names btw :D). They allow an interface pointer to be marshaled to a different thread, so the other thread can make calls on the object as well. I have not used these myself yet, but the description looks like they are pretty straight-forward to use.

Posted: Sat Mar 21, 2009 11:18 pm
by srod
Yes I realise that the STA requires marshalling of the interface pointers and was looking at those functions earlier on this evening. :) Doesn't fit very well into COMate though; although I could add this without too much trouble I reckon. :)

Someone earlier was trying to pass an Excel object pointer through a global variable to a thread, which of course requires the aforementioned marshalling of interface pointers within STA and which of course consequently failed due to the lack of such marshalling.

Still, considering what you have just said I think that I should reinstate COMate's use of STA rather than run the risk of upsetting PB too much! :) I will think about whether it is worth my time adding the marshalling aspect.

Thanks for the reply.