Re: Returning IStream as IDisPatch causes crash in VB?

Tech-Archive recommends: Fix windows errors by optimizing your registry

From: Kim Gräsman (kim_at_mvps.org)
Date: 03/20/04


Date: Sat, 20 Mar 2004 12:35:00 +0100

Hi Bruce,

> STDMETHODIMP CMyObject::get_MyStream(IDispatch **ppVal)
> {
>
> HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,1000);
> LPVOID pvData = GlobalLock(hGlobal);
> LPSTREAM pStream = NULL;
> HRESULT hr = CreateStreamOnHGlobal(hGlobal,TRUE,&pStream);
> *ppVal = (IDispatch*)pStream;
> (*ppVal)->AddRef();
>
> return S_OK;
> }

Any way you look at it, a pointer to IDispatch is not the same as a pointer
to IStream, which the following line is trying to convince the compiler:

> *ppVal = (IDispatch*)pStream;

The crash is happening because VB is trying to locate some method, either in
IDispatch or IUnknown, and call it, but the signature available in the
IStream interface doesn't match what it's expecting, so the stack is
trashed, and the application blows up.

Also, the allocation of memory is not necessary - if you pass NULL to
CreateStreamFromHGlobal, it creates a growable stream behind-the-scenes:

STDMETHODIMP CMyObject::get_MyStream(IDispatch **ppVal)
{
 CComPtr<IStream> spStream;
 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &spStream);

 CComPtr<IDispatch> spRetVal;
 hr = ConstructSomeObjectWrappingTheStream(spStream, &spRetVal);

 *ppVal = spRetVal.Detach();

 return S_OK;
}

Now what you need to do, is to write some object wrapping the IStream
interface, and exposing it as an IDispatch interface, with
automation-compatible parameter types.

Casting is never the right thing to do.

-- 
Best regards,
Kim Gräsman


Relevant Pages

  • Re: Returning IStream as IDisPatch causes crash in VB?
    ... Microsoft MVP, MCSD ... IDispatch implementation. ... > return an IStream as an IDsipatch to make it compatible with another COM ... >> IStream interface doesn't match what it's expecting, ...
    (microsoft.public.vc.atl)
  • Getting IDispatch from IUnknown
    ... i'm currentlly extending an script interpreter with a COM interface (or ... got some problems to get a pointer to the IDispatch interface, ... So how do i "convert" the IUnknown pointer to a IDispatch pointer? ...
    (microsoft.public.win32.programmer.ole)
  • Re: Returning IStream as IDisPatch causes crash in VB?
    ... State what that control really needs. ... IDispatch implementation. ... > return an IStream as an IDsipatch to make it compatible with another COM ... >> IStream interface doesn't match what it's expecting, ...
    (microsoft.public.vc.atl)
  • Re: Creating an IStream wrapper?
    ... you should create a simple object, make it support dual interface. ... and you do IStream read write there. ... > Then how do I cast the IUnknown to an IDispatch in VB??? ...
    (microsoft.public.vc.atl)
  • Re: problem calling function of atl control created dynamically
    ... >> pointer. ... QI for the right interface you need! ... What's the type of pToolband? ... pointed to by pToolband will be that of IDispatch. ...
    (microsoft.public.vc.atl)