Marshalling
-
hi i have a vc++6 MFC app. in my main i start a thread that connects to the wmi of a host, it uses IWbemLocator *pLoc IWbemServices *pSvc back in the main, once the thread has finished connecting to the wmi of the host, it is queryied but the two global variables above are "empty", this is because you cannot use COM interfaces on multiple threads and each thread must initialize COM itself and onyl use local COM objects afaik. so i think marshalling will have to be used but i dont know where to start on how to implement it please help
-
hi i have a vc++6 MFC app. in my main i start a thread that connects to the wmi of a host, it uses IWbemLocator *pLoc IWbemServices *pSvc back in the main, once the thread has finished connecting to the wmi of the host, it is queryied but the two global variables above are "empty", this is because you cannot use COM interfaces on multiple threads and each thread must initialize COM itself and onyl use local COM objects afaik. so i think marshalling will have to be used but i dont know where to start on how to implement it please help
Whenever you cross apartment boundaries you have to marshal the interface. An apartment is, in simple words, a thread that has made a successful call to ::CoInitialize() or similar. Each thread that will use COM in any way have to initialize COM by calling ::CoInitialize(), which tells the COM subsystem that this-apartment-is-a-single-threaded-apartment (STA). If you want your thread to be added the the multithreaded apartment of the process (MTA), because there can be only one, you have to call ::CoInitializeEx() with COINIT_MULTITRHEADED. The easiest way to marshal an interface is to use ::CoMarshalInterThreadInterfaceInStream()[^] and ::CoGetInterfaceAndReleaseStream. Hope this helps -- Roger
It's supposed to be hard, otherwise anybody could do it!
-
Whenever you cross apartment boundaries you have to marshal the interface. An apartment is, in simple words, a thread that has made a successful call to ::CoInitialize() or similar. Each thread that will use COM in any way have to initialize COM by calling ::CoInitialize(), which tells the COM subsystem that this-apartment-is-a-single-threaded-apartment (STA). If you want your thread to be added the the multithreaded apartment of the process (MTA), because there can be only one, you have to call ::CoInitializeEx() with COINIT_MULTITRHEADED. The easiest way to marshal an interface is to use ::CoMarshalInterThreadInterfaceInStream()[^] and ::CoGetInterfaceAndReleaseStream. Hope this helps -- Roger
It's supposed to be hard, otherwise anybody could do it!
so will i get away with using CoInitializeEx() with COINIT_MULTITRHEADED and not having to use marshalling?
-
so will i get away with using CoInitializeEx() with COINIT_MULTITRHEADED and not having to use marshalling?
no! the CoInitializeEx() with COINIT_MULTITRHEADED tells what type of apartment do you wishes to use in yourcase MTA. unfortunately, you will have to do marshaling yourself,use the 2 methods suggested above hope it helps Ask not what your application can do for you, Ask what you can do for your application
-
so will i get away with using CoInitializeEx() with COINIT_MULTITRHEADED and not having to use marshalling?
viperlogic wrote:
so will i get away with using CoInitializeEx() with COINIT_MULTITRHEADED and not having to use marshalling?
In theory this is possible and usually requires the free-threaded-marshaler (FTM) and you also have to be aware that when your thread that created the server finishes it has to call ::CoUninitalize() which unloads the COM library for that thread which can get you into trouble. It also depends on the server whether it supports free-threading or not. The use of free-threading is usually complicated and not for the faint-hearted. If you really want to create the server to be created in a secondary thread, I suggest you create the server and marshal the interface back to the main thread, or whatever thread you like, by ::CoMarshalInterThreadInterfaceInStream() and ::CoGetInterfaceAndReleaseStream(). You can alert the receiving thread by posting a message or setting an event informing the thread that the server is created and the interface can be retrieved with ::CoGetInterfaceAndReleaseStream(). This is not so complicated compared to free-threading. In other words: a good place to start. N.B. since this kind of questions are COM related you should post in the COM forum instead. Hope this helps -- Roger
It's supposed to be hard, otherwise anybody could do it!