Board index » cppbuilder » Accessing a com obj. in main vcl thread from a another thread, using functions from the main thread

Accessing a com obj. in main vcl thread from a another thread, using functions from the main thread

Hi ...

I have a vcl component that has an Event sink and a interface pointer used
to create a COM obj using a COM server,
and to call functions in this COM obj. / to receive events from it through
the event sink obj.

The component exposes some functions that access the interfaceptr and hereby
are able to send data to the COM server.

My component also has a TThread object, which has function ptrs to which the
components' event handlers are mapped,
effectively making the components event handlers run i the TThread instead
of the components Main VCL thread.

The problem is when I for instance plug the component onto a Form, assign a
event handler to the component, and in this event handler
call one of the components functions that send data to the COM obj.

The problem is that when I put a breakpoint in the function, like shown
below, a non-zero value is returned.
HRESULT hr = MyInterFacePtr->SomeFunctionThatSendsDataToTheCOMServer(...)
/* hr = -2147221008  */
and no data is sent to the COM server (I also planted a breakpoint threre,
just to make sure).

I should comment that there is no problem calling the components functions
outside the event handlers, and all events are also correctly received,
the only trouble is that I can't seem to call the functions of the
components Main VCL thread from within the TThread.

Why is this so, and can I make it work ?

I read the post by "Juan Diego Garces" with the topic "Problem with a
multithreaded client", and tried adding the line
CoInitializeEx(NULL,COINIT_MULTITHREADED); to the constructor of both my
component and the thread, and
also the line
CoUninitialize(); in the components destructor and after the threads Execute
metod.
But still nothing.

I'm using C++ Builder 5.0 and my Project Options | ATL are
    Instancing = Multi use
    OLE Initialization COINIT xxxx Flag = MultiThreaded
    Threading Model = Apartment

Best Regards
Kurt

 

Re:Accessing a com obj. in main vcl thread from a another thread, using functions from the main thread


Quote
"Kurt Andersen" <k...@nospam.eegholm.dk> wrote in message

news:3d2c0365$1_2@dnews...

Quote
> The problem is that when I put a breakpoint in the function, like
> shown below, a non-zero value is returned.
> HRESULT hr = MyInterFacePtr->SomeFunctionThatSendsDataToTheCOMServer(...)
> /* hr = -2147221008  */
> and no data is sent to the COM server (I also planted a breakpoint threre,
> just to make sure).

-2147221008 = "CoInitialize has not been called."

You need to call CoInitialize() at the beginning of your thread, and
CoUnintialize at the end.

Quote
> I read the post by "Juan Diego Garces" with the topic "Problem
> with a multithreaded client", and tried adding the line
> CoInitializeEx(NULL,COINIT_MULTITHREADED); to the
> constructor of both my component and the thread, and
> also the line CoUninitialize(); in the components destructor and
> after the threads Execute metod.
> But still nothing.

You can't use the thread's constructor, because it is called in the context
of the *calling* thead, not in the context of the new thread that is being
created.  Only Execute() and DoTerminate() are called in the context of the
actual thread.  You need to call CoIninitalize/Ex() at the beginning of
Execute() instead.  I prefer to always override DoTerminate() as well, and
call CoUninitialize() from there, so that in case Execute() ever happens to
exit prematurely, DoTerminate() is still called to perform the necessary
cleanup.

Gambit

Re:Accessing a com obj. in main vcl thread from a another thread, using functions from the main thread


Thanks Remy

I got my code working now, however I was wondering where I could find the
definitions of there
error codes. I tried msdn but only found some "common COM errors" and not
the one you
decifered for me.

Btw... I'm not sure this is the rigth NG for this question but I'll try
anyway.
When the thread I have in my component fires an event, the event handler in
the Form
the component is placed on is called.
But ... will the event handler execute in my tthread obj og in the vcl
thread in which the Form is running ?
If it is executing in the Forms thread there should be no problem, however
if it is executing in
the tthread obj there will be problems when using the vcl, right ? (vcl not
thread-safe)

/Kurt

"Remy Lebeau [TeamB]" <gambi...@yahoo.com> wrote in message
news:3d2c66a8$1_2@dnews...

Quote

> "Kurt Andersen" <k...@nospam.eegholm.dk> wrote in message
> news:3d2c0365$1_2@dnews...

> > The problem is that when I put a breakpoint in the function, like
> > shown below, a non-zero value is returned.
> > HRESULT hr =

MyInterFacePtr->SomeFunctionThatSendsDataToTheCOMServer(...)
Quote
> > /* hr = -2147221008  */
> > and no data is sent to the COM server (I also planted a breakpoint
threre,
> > just to make sure).

> -2147221008 = "CoInitialize has not been called."

> You need to call CoInitialize() at the beginning of your thread, and
> CoUnintialize at the end.

> > I read the post by "Juan Diego Garces" with the topic "Problem
> > with a multithreaded client", and tried adding the line
> > CoInitializeEx(NULL,COINIT_MULTITHREADED); to the
> > constructor of both my component and the thread, and
> > also the line CoUninitialize(); in the components destructor and
> > after the threads Execute metod.
> > But still nothing.

> You can't use the thread's constructor, because it is called in the
context
> of the *calling* thead, not in the context of the new thread that is being
> created.  Only Execute() and DoTerminate() are called in the context of
the
> actual thread.  You need to call CoIninitalize/Ex() at the beginning of
> Execute() instead.  I prefer to always override DoTerminate() as well, and
> call CoUninitialize() from there, so that in case Execute() ever happens
to
> exit prematurely, DoTerminate() is still called to perform the necessary
> cleanup.

> Gambit

Other Threads