Solved

Passing COM object between threads

Posted on 2001-06-07
8
421 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 3

Expert Comment

by:GlennDean
ID: 6165646
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
ID: 6168220
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
ID: 6168260
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Accepted Solution

by:
GlennDean earned 100 total points
ID: 6168575
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
 

Author Comment

by:c095276
ID: 6168866
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
ID: 6168883
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
ID: 6171380
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
ID: 9484584
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 Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Excel Use VBA to get user's Mac Address for their computer 5 415
Smart Camera scanning and reading information 3 127
has77  challenge 9 106
Grunt No Clean Targets 6 306
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
Suggested Courses

752 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