15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CoCreateInstance() from the second thread

Max Paklin -- mpaklin@auravision.com
Friday, December 06, 1996

Environment: VC++ 4.2b, Win95

Hi, netters!

I'm using COM in the main thread of my app and all work as usual. And this
time I need to instantiate one more object but I wanna do it from separate
thread. I was sure it's easy (and it seems to me it should) but I got some
problem and ask somebody to help me.


I had the next code working fine:

void CMyDoc::OnConfigure()
{
    IMyInterface* piMy;
    HRESULT hResult = CoCreateInstance( CLSID_MyObject, NULL,
                        CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&piMy );
    if( SUCCEEDED( hResult ) )
    {
        // Doing something
        piMy->Release();
    }
}


And then wanted to get this working:

UINT AFX_CDECL MyThread( LPVOID pParam )
{
    IMyInterface* piMy;
    HRESULT hResult = CoCreateInstance( CLSID_MyObject, NULL,
                        CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&piMy );
    if( SUCCEEDED( hResult ) )
    {
        // Doing something
        piMy->Release();
    }
}
void CMyDoc::OnConfigure()
{
    AfxBeginThread( MyThread, NULL );
}

But got the next error: "CoInitialize has not been called" in
CoCreateInstance().

Okay, I did not expect it but it looks like CoInitialize()/CoUninitialize()
pair must be called from every thread. Right?
I corrected it:

UINT AFX_CDECL MyThread( LPVOID pParam )
{
    if( SUCCEEDED( CoInitialize( NULL ) ) )
    {

        // The same stuff

        CoUninitialize();
    }
}

In this case CoCreateInstance() returns: 0x80040155
That means "Interface not registered"
and trace error in debugger window:
First-chance exception in MyExe.exe (KERNEL32.DLL): 0x80040155: (unknown).

Looks like it's not possible to instantiate objects from different threads.
In Win32 help I found reference on CoInitializeEx( NULL,
COINIT_MULTITHREADED ) and
that time thought that it is what I need. But unfortunately CoInitializeEx()
is supposed to be called only under NT (and Win95 with DCOM?).

Can somebody please help me?

Thank you.
Max.




Randy Sales -- rsc@halcyon.com
Monday, December 09, 1996

[Mini-digest: 2 responses]

Max,

I had the same problem under NT and had to establish separate apartments
for each thread via registry entries.  Check the archives of this mail
list for complete details.  Just search on keywords of 'apartment' and
'ThreadingModel'.

I must say I'm not sure the same solution will work under Windows 95.
Does
anyone else know for sure?

Randy Sales

-- 
RS Consulting
1521 1/2 Cedar Street
Everett, WA 98201

Phone   206-259-1056
Fax     206-259-1315
email   rsc@halcyon.com

Max Paklin wrote:
> 
> Environment: VC++ 4.2b, Win95
> 
> Hi, netters!
> 
> I'm using COM in the main thread of my app and all work as usual. And this
> time I need to instantiate one more object but I wanna do it from separate
> thread. I was sure it's easy (and it seems to me it should) but I got some
> problem and ask somebody to help me.
> 
> I had the next code working fine:
> 
> void CMyDoc::OnConfigure()
> {
>     IMyInterface* piMy;
>     HRESULT hResult = CoCreateInstance( CLSID_MyObject, NULL,
>                         CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&piMy );
>     if( SUCCEEDED( hResult ) )
>     {
>         // Doing something
>         piMy->Release();
>     }
> }
> 
> And then wanted to get this working:
> 
> UINT AFX_CDECL MyThread( LPVOID pParam )
> {
>     IMyInterface* piMy;
>     HRESULT hResult = CoCreateInstance( CLSID_MyObject, NULL,
>                         CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&piMy );
>     if( SUCCEEDED( hResult ) )
>     {
>         // Doing something
>         piMy->Release();
>     }
> }
> void CMyDoc::OnConfigure()
> {
>     AfxBeginThread( MyThread, NULL );
> }
> 
> But got the next error: "CoInitialize has not been called" in
> CoCreateInstance().
> 
> Okay, I did not expect it but it looks like CoInitialize()/CoUninitialize()
> pair must be called from every thread. Right?
> I corrected it:
> 
> UINT AFX_CDECL MyThread( LPVOID pParam )
> {
>     if( SUCCEEDED( CoInitialize( NULL ) ) )
>     {
> 
>         // The same stuff
> 
>         CoUninitialize();
>     }
> }
> 
> In this case CoCreateInstance() returns: 0x80040155
> That means "Interface not registered"
> and trace error in debugger window:
> First-chance exception in MyExe.exe (KERNEL32.DLL): 0x80040155: (unknown).
> 
> Looks like it's not possible to instantiate objects from different threads.
> In Win32 help I found reference on CoInitializeEx( NULL,
> COINIT_MULTITHREADED ) and
> that time thought that it is what I need. But unfortunately CoInitializeEx()
> is supposed to be called only under NT (and Win95 with DCOM?).
> 
> Can somebody please help me?
> 
> Thank you.
> Max.
-----From: Randy Sales 

Max,

This is a follow-up to my previous answer.  I subscribe to two
mail lists, the other one is:

    Distributed COM-Based Code 

I sometimes answer questions like your thinking they came from
that mail list cause that's typical of the kind of questions asked
there.  So to be more exact, you may need to make all objects in
your inproc server multi-thread capable by adding the string:

    ThreadingModel=Apartment

to their entries in the registry.  The MSDN provides several
detailed descriptions of this process.  If you don't have it,
you could go microsoft.com and search on those keywords, the
KB articles are likely to be there.  Or just go search the
archives of the DCOM mail list above and you find the details
I mentioned in the previous email.

Randy Sales

-- 
RS Consulting
1521 1/2 Cedar Street
Everett, WA 98201

Phone   206-259-1056
Fax     206-259-1315
email   rsc@halcyon.com




| Вернуться в корень Архива |