Note:
Question:
Illustration:
IS8Simulation *pis8 = NULL;
...
CoCreateInstance(
clsid,
NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IS8Simulation),
(void **) &pis8);
...
hThread = CreateThread(
NULL,
0,
SecondaryThread,
//interface pointer pis8
0,
&dwGenericThreadID);
...
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
//using iValue accordingly
//E.g.: iValue->Open
Regards
As was stated below, passing a COM
interface pointer between threads in not safe.
Assuming you know what you are doing:
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) pis8
0,
&dwGenericThreadID);
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
((IS8Simulation*) iValue)->Open();
}
Thread safe version:
void MainThread()
{
IStream* psis8;
HRESULT res = CoMarshalInterThreadInterfaceInStream (IID_IS8SIMULATION, pis8, &psis8);
if (FAILED(res))
return;
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) psis8
0,
&dwGenericThreadID
);
}
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
IS8Simulation* pis8;
HRESULT res = CoGetInterfaceAndReleaseStream((IStream*) iValue, IID_IS8SIMULATION, &pis8);
if (FAILED(res))
return (DWORD) res;
pis8->Open();
}
If the interface in your question is a COM interface, the approach given by Quassnoi might not be sufficient. You have to pay attention to the threading-model of the COM object in use. If the secondary thread will join a separate COM apartment from the one that your COM object was created in, and if that object is not apartment-agile, you'll need to marshal that interface pointer so that the secondary thread gets a proxy, and not a direct pointer to the object.
A COM object is normally made apartment-agile by using a special implementation of IMarshal. The simplest approach is to aggregate the Free Threaded Marshaler.
Some useful links...
Update: About the Free-threaded Marshaler...
It's clear from comments on this topic that some people would recommend that you never touch the FTM. While "Effective COM" is an excellent book, I think some of its recommendations are open to interpretation. Item 33 says "Beware the FTM"; it does not say "Never use the FTM". Very wisely it advises caution particularly when your apartment-agile object holds references to other objects, because they might not be apartment-agile. So really the advice is: think carefully when building apartment-agile objects, whether or not they use the FTM to achieve their agility. If you're sure you can build an apartment-agile object, I see no reason why you wouldn't use the FTM to achieve that.
You basically need to do the following:
CoMashalInterThreadInterfaceInStream
==> you get an IStream interface. CoGetInterfaceAndReleaseStream
to get the interface (or a proxy to it, if necessary). Do not release the IStream interface unless creating the thread fails, and don't exit the thread until yu have called CoGetInterfaceAndReleaseStream
.
COM runtime will create the proxy for you automatically. The proxy ensures that e.g. an apartment-threaded COM component is called on the thread that created it. However, this also requires that:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With