Solved

Passing COM object between threads

Posted on 2001-06-07
8
417 Views
Last Modified: 2013-11-20
I have a COM object that was written in VB which I use in a VC++ app.  I am passing a pointer to the object between two threads.  The creating thread uses a new to create the thread, calls the objects CreteaDispatch as so  someCOMMObj->CreateDispatch( CLSID_SOMECLASS), and calls some of the objects function in order to initialize it.  This all works fine.  I pass the object as shown below

AfxBeginThread(SomeThread::InquiryThreadProc, someCOMObj);

SomeThread receives the pointer properly, which means that I have looked at the address and know that they are the same.  I then call CoInitialize( NULL) from the receiving thread, but when I go to call any function of the Com object an exception of some type is thrown.  It is not a COleDispatchException *, or CException * I am explicitly catching those.  What could be going on?  Is there any way that I can tell wat the exception is that is being thrown?

Thanks
0
Comment
Question by:c095276
8 Comments
 
LVL 3

Expert Comment

by:GlennDean
Comment Utility
I wouldn't pass someCOMObj, but rather IUnknown * and let the thread query for whatever interface it needs.  Something like

AfxBeginThread(SomeThread::InquiryThreadProc, (LPVOID)someCOMObj->GetControllingUnknown());

0
 

Author Comment

by:c095276
Comment Utility
I have not had a chance to try your suggestion yet Glenn, but I did discover something else.  I did a CoInitialize( NULL) and a CreateDispatch on each thread as I passed the object around.  This time I recieved a CException error that says, "The application called an interface that was marshalled for a different thread."  Will your suggestion still work or is it something else?

Thanks

0
 

Author Comment

by:c095276
Comment Utility
Glenn,
  What do you mean by "let the thread query for whatever interface it needs."  Could you show me some code on the receiving side, that is the UINT SomeThread::InquiryThreadProc( LPVOID pParam) function, on how to handle the IUnknown pointer.

Thanks again
0
 
LVL 3

Accepted Solution

by:
GlennDean earned 100 total points
Comment Utility
What I mean is the standard COM marshaller (i.e. oleaut32.dll) can't (to the best of my knowledge) marshall arbitrary interface pointers around.  It can only marshall IUnknown * and IDispatch * from client to server and vice versa.  
   What I was thinking you should try is this: let's say you wanted to pass IMyInterface * pMyInt to a client.  Then go
IUnknown * pUnk;
pMyInt->QueryInterface(IID_IMyInterface,(void **)&pUnk);

Then pass pUnk to client.  

In the client, query for the interfaces it needs (say they are IMyInterface and IMySecondInterface):
IMyInterface * pMyInt;
IMySecondInterface * pMySecInt;
pUnk->QueryInterface(IID_IMyInterface,(void **)&pMyInt);
pUnk->QueryInterface(IID_IMySecondInterface,(void **)&pMySecInt);

I'm not sure the above will work (I do the above when the client and the server are both COM objects) since you will be passing pUnk to a thread.  

Also, don't forget to call CoInitialize inside the thread.

   Glenn
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:c095276
Comment Utility
I discovered that the CoInitialize works on an apartment thread model.  I assume that I need more of a free threading model, so I was going to switch to CoInitializeEx and specify COINIT_MULTITHREADED.  When I compile I receive an error, "'CoInitializeEx' : undeclared identifier"  The header file objbase.h includes this function but it is defined only if
(_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)

What is the right way to specify these preprocessor directives?  Are they specifed in the project settings?
0
 
LVL 3

Expert Comment

by:GlennDean
Comment Utility
I've run into that problem many times.  I just add _WIN32_DCOM to my preprocessor defines (i.e Project -> Settings -> C/C++ tab, Category = Preprossor, Preprocessor defines edit box) and everything works fine.

  Glenn
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
since your componant is VB I think it is apartment only - so to marshal it between apartments you should use (ready for this is its a biggie)

CoMarshalInterThreadInterfaceInStream(...) - to marshal the pointer to a stream

CoGetInterfaceAndReleaseStream(...) - to get it from the stream

this technique and others are demonstrated in the following MS KB article http://support.microsoft.com/support/kb/articles/Q206/0/76.ASP
0
 
LVL 23

Expert Comment

by:Roshan Davis
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered by : GlennDean, ShaunWilde (points to be split)

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Before we dive into the marketing strategies involved with creating an effective homepage, it’s crucial that EE members know what a homepage is. In essence, a homepage is the introductory, or default page, of a website that typically highlights the …
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now