Click to See Complete Forum and Search --> : How do I pass a smart pointer in SendMessage?


Dorothy Nelson
June 2nd, 1999, 08:35 PM
Arg! This is killing me. I know there is a disgustingly easy answer to this.

Every time I pass a regular cached COM pointer around, it is not a problem. But when I try to SendMessage a smart pointer I either get a) casting problems if I just pass it without &-ing it or b) if I do & it, the pointer at the recipient end of SendMessage now points to... NULL. Every time.

I know the answer is a one liner... please please help a frazzled gal... it must be some way to make the smart pointer give up its smartness to become a regular COM pointer.

Thanks in advance.

RajM
June 2nd, 1999, 08:54 PM
hi,
can u give me the code where u send and receive the smart pointer?need a more clear picture of the situation

June 2nd, 1999, 10:14 PM
Are you passing that pointer to other processes with SendMessage? If so, you will have to marshal that pointer across processes using the CoMarshalInterface API call. Basically, the following occurs:

1. The passer marshals the pointer with CoMarshalInterface. This method returns an IStream pointer to you.
2. The passer sends that IStream pointer to someone else(you would be doing it with SendMessage).
3. The reciever calls CoUnmarshalInterface with its IStream pointer. That should return the smart pointer for you.

Give this a shot. It might be the solution to your problem.

Dorothy Nelson
June 3rd, 1999, 11:12 AM
Hi Raj,

It's just a simple SendMessage (from a View whose Document caches the smart pointer) to CMainFrame, which uses it and SendMessage's it to all active Status View classes.

Here's the call:
CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd( );
pMain->SendMessage(WM_STATUS_TDLERROR, (WPARAM)0, (LPARAM)(&(pDoc->m_IParseErrorsPtr)));

It is consumed here:

LRESULT CStatusDockView::OnStatusError(WPARAM wParam, LPARAM lParam)
{
// Save TDL Parse Error object
if (lParam != NULL)
{
// *pptr == NULL here
IParseErrorsPtr *pptr = (IParseErrorsPtr *)lParam;
}
}

No weird cross processes or anything... all synchronous. I'll use Anonymous' suggestion of using the CoMarshalInterface if I have to, but I think his solution is more for cross-process communication. If there is an easier way I'd prefer to use it.

MANY thanks...
--Dorothy

RajM
June 3rd, 1999, 12:38 PM
Hi dorothy,
make the following changes(i assume that the interface encapsulated by the smart pointer is IParseErrors)
IParseErrors *pI=(IParseErrors*)
(pDoc->m_IParseErrorsPtr);
pMain->SendMessage(WM_STATUS_TDLERROR, (WPARAM)0, (LPARAM)pI);




LRESULT CStatusDockView::OnStatusError(WPARAM wParam, LPARAM lParam)
{
// Save TDL Parse Error object
if (lParam != NULL)
{
IParseErrorsPtr ptr((IParseErrors*)lParam);
use pptr here
}
}
I tried this way of passing pointers and it works.U are passing the actual pointer and not the smart pointer but u reconvert it back as a smart pointer on the receiving side.tell me if thsi works for u.
-Raj

RajM
June 3rd, 1999, 12:40 PM
Hi,
A correction.
LRESULT CStatusDockView::OnStatusError(WPARAM wParam, LPARAM lParam)
{
// Save TDL Parse Error object
if (lParam != NULL)
{
IParseErrorsPtr<IID_IParseErrors> ptr((IParseErrors*)lParam);

use pptr here

}
}

Tomaz Stih
June 3rd, 1999, 12:45 PM
Hi Dorothy. Are you perhaps sending your pointer out of Kansas? :-) When giving another process access to your your COM object you have to do marshalling.

---------------------------------------------
Tomaz Stih, B.Sc.CS tomaz@nameco.com
Ob sotoccju 10 Nameco Group
SI-1000 Ljubljana http://www.nameco.com
Europe

Dorothy Nelson
June 3rd, 1999, 01:27 PM
Raj,

You're the tops! This solution worked fabulously well! The correction one didn't compile, but it doesn't matter, I think, the first post did the trick.

Again, thanks for your expertise!

Warm regards,
Dorothy