Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RpcRaiseException called from RpcRt4.DLL, generating 80004002 - No such interface supported

137 views
Skip to first unread message

J. R. Antley

unread,
Jan 17, 2003, 7:53:42 PM1/17/03
to
Hi NG:

I'm hoping somebody can shed some light on this problem. This code
has worked for some time in a production environment. Suddenly it
began blowing up in my development environment, and I can reproduce
the problem at will.

The code looks something like (simplified for clarity):

COM Client:

CComPtr<ITrcQueueItem> item;
HRESULT hr = w->AcquireItem(&item); // 0x80004002???

COM Server:

STDMETHODIMP CTrcSSBWorkflow::AcquireItem(ITrcQueueItem* *
pItem)
{
::CoCreateInstance( CLSID_QueueItem, NULL, CLSCTX_ALL,
IID_ITrcQueueItem, (void**)pItem);
pItem->set_Prop1(...);
// ...
return (S_OK);
}

When AcquireItem returns, everything appears to be hunky dory.
However, it returns to the bowels of the dispatch code, which
generates an exception, which I have captured in the debugger:

Call Stack on return from AcquireItem:
> rpcrt4.dll!NdrServerInitialize() + 0x288
rpcrt4.dll!NdrStubCall2() + 0x570
rpcrt4.dll!CStdStubBuffer_Invoke() + 0xc5
OLEAUT32.DLL!UserEXCEPINFO_free_local() + 0x2114
OLE32.DLL!HACCEL_UserMarshal() + 0x679
OLE32.DLL!CoGetCallContext() + 0x401
OLE32.DLL!CoGetCallContext() + 0x34d
OLE32.DLL!CoGetCallContext() + 0xb43
OLE32.DLL!HACCEL_UserMarshal() + 0x51b
OLE32.DLL!HACCEL_UserMarshal() + 0x394
OLE32.DLL!HACCEL_UserMarshal() + 0xab7
OLE32.DLL!CoGetCallContext() + 0xa76
USER32.DLL!SetWindowPlacement() + 0x50
USER32.DLL!TranslateMessageEx() + 0x605
USER32.DLL!DispatchMessageW() + 0xb
OLE32.DLL!StgOpenStorageEx() + 0x15ea
OLE32.DLL!StgOpenStorageEx() + 0x151d

Call Stack when exception is generated:
> KERNEL32.DLL!RaiseException() + 0x56
rpcrt4.dll!RpcRaiseException() + 0x1c
rpcrt4.dll!NdrServerContextNewUnmarshall() + 0x122
rpcrt4.dll!NdrPointerMarshall() + 0x29
rpcrt4.dll!CStdStubBuffer_Invoke() + 0xc5
OLEAUT32.DLL!UserEXCEPINFO_free_local() + 0x2114
OLE32.DLL!HACCEL_UserMarshal() + 0x679
OLE32.DLL!CoGetCallContext() + 0x401
OLE32.DLL!CoGetCallContext() + 0x34d
OLE32.DLL!CoGetCallContext() + 0xb43
OLE32.DLL!HACCEL_UserMarshal() + 0x51b
OLE32.DLL!HACCEL_UserMarshal() + 0x394
OLE32.DLL!HACCEL_UserMarshal() + 0xab7
OLE32.DLL!CoGetCallContext() + 0xa76
USER32.DLL!SetWindowPlacement() + 0x50
USER32.DLL!TranslateMessageEx() + 0x605
USER32.DLL!DispatchMessageW() + 0xb
OLE32.DLL!StgOpenStorageEx() + 0x15ea
OLE32.DLL!StgOpenStorageEx() + 0x151d

This results in hr being set to 0x80004002 and causes me great angst.
Any advice appreciated.

Thanks in advance,
JR

Alexander Nickolov

unread,
Jan 17, 2003, 8:15:21 PM1/17/03
to
Check the marshaling support for ITrcQueueItem (it's proxy/stub DLL).
Looks like it's out of date with regard to the rest of the code...

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"J. R. Antley" <john_...@rhco.com> wrote in message news:70038508.03011...@posting.google.com...

J. R. Antley

unread,
Jan 21, 2003, 10:12:16 AM1/21/03
to
Thanks for the response, Alexander. I do find it somewhat puzzling,
however. All of my COM objects are in-process DLLs. I didn't think I
needed to use marshalling and have not compiled or registered the
proxy server dll. Since they are derived of IDispatch, they should
use OLEAUT32.DLL auto-marshalling, right? As we can see,
CStdStubBuffer_Invoke from that DLL is indeed on the call stack in a
very suspicious location.

So why would he fail? *G* A little more information. I've also
developed some .NET interfaces with COM interop which implement
ITrcQueueManager and ITrcQueueItem interfaces.

The .NET code retrieves items into my queue from SQL Server, where the
old C++ implementation reads it from an Exchange Server, FYI, so you
might understand why I wanted to do this in the first place. Changing
a ProgID in the configuration utility, the application can be swapped
from one Queuing mechanism to the other.

Could this be causing my old ITrcQueueItem or ITrcQueueManager
implementation to be unhappy? I've looked, but I don't see how.

Regards,
JR


"Alexander Nickolov" <agnic...@mvps.org> wrote in message news:<OXlgn7ovCHA.2380@TK2MSFTNGP11>...


> Check the marshaling support for ITrcQueueItem (it's proxy/stub DLL).
> Looks like it's out of date with regard to the rest of the code...
>
> --
> =========================
> ============
> Alexander Nickolov
> Microsoft MVP [VC], MCSD
> email: agnic...@mvps.org
> MVP VC FAQ: http://www.mvps.org/vcfaq
> =========================
> ============
>

> "J. R. Antley" <john ant...@rhco.com> wrote in message

> news:70038508.03011...@posting.google.com...
> > Hi NG:
> >
> > I'm hoping somebody can shed some light on this problem. This code
> > has worked for some time in a production environment. Suddenly it
> > began blowing up in my development environment, and I can reproduce
> > the problem at will.
> >
> > The code looks something like (simplified for clarity):
> >
> > COM Client:
> >
> > CComPtr<ITrcQueueItem> item;
> > HRESULT hr = w->AcquireItem(&item); // 0x80004002???
> >
> > COM Server:
> >
> > STDMETHODIMP CTrcSSBWorkflow::AcquireItem(ITrcQueueItem* *
> > pItem)
> > {

> > ::CoCreateInstance( CLSID QueueItem, NULL, CLSCTX ALL,
> > IID ITrcQueueItem, (void**)pItem);
> > pItem->set Prop1(...);
> > // ...
> > return (S OK);


> > }
> >
> > When AcquireItem returns, everything appears to be hunky dory.
> > However, it returns to the bowels of the dispatch code, which
> > generates an exception, which I have captured in the debugger:
> >
> > Call Stack on return from AcquireItem:
> > > rpcrt4.dll!NdrServerInitialize() + 0x288
> > rpcrt4.dll!NdrStubCall2() + 0x570

> > rpcrt4.dll!CStdStubBuffer Invoke() + 0xc5
> > OLEAUT32.DLL!UserEXCEPINFO free local() + 0x2114
> > OLE32.DLL!HACCEL UserMarshal() + 0x679

> > OLE32.DLL!CoGetCallContext() + 0x401
> > OLE32.DLL!CoGetCallContext() + 0x34d
> > OLE32.DLL!CoGetCallContext() + 0xb43

> > OLE32.DLL!HACCEL UserMarshal() + 0x51b
> > OLE32.DLL!HACCEL UserMarshal() + 0x394
> > OLE32.DLL!HACCEL UserMarshal() + 0xab7

> > OLE32.DLL!CoGetCallContext() + 0xa76
> > USER32.DLL!SetWindowPlacement() + 0x50
> > USER32.DLL!TranslateMessageEx() + 0x605
> > USER32.DLL!DispatchMessageW() + 0xb
> > OLE32.DLL!StgOpenStorageEx() + 0x15ea
> > OLE32.DLL!StgOpenStorageEx() + 0x151d
> >
> > Call Stack when exception is generated:
> > > KERNEL32.DLL!RaiseException() + 0x56
> > rpcrt4.dll!RpcRaiseException() + 0x1c
> > rpcrt4.dll!NdrServerContextNewUnmarshall() + 0x122
> > rpcrt4.dll!NdrPointerMarshall() + 0x29

> > rpcrt4.dll!CStdStubBuffer Invoke() + 0xc5
> > OLEAUT32.DLL!UserEXCEPINFO free local() + 0x2114
> > OLE32.DLL!HACCEL UserMarshal() + 0x679

> > OLE32.DLL!CoGetCallContext() + 0x401
> > OLE32.DLL!CoGetCallContext() + 0x34d
> > OLE32.DLL!CoGetCallContext() + 0xb43

> > OLE32.DLL!HACCEL UserMarshal() + 0x51b
> > OLE32.DLL!HACCEL UserMarshal() + 0x394
> > OLE32.DLL!HACCEL UserMarshal() + 0xab7

Alexander Nickolov

unread,
Jan 21, 2003, 3:47:31 PM1/21/03
to

If you are using TLB-driven marshaling, that only shifts the problem
to an inconsistency with your TLB. Perhaps some client needs to be
recompiled...

--
=====================================


Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq

=====================================

"J. R. Antley" <john_...@rhco.com> wrote in message news:70038508.03012...@posting.google.com...

J. R. Antley

unread,
Jan 22, 2003, 4:59:28 AM1/22/03
to
I think I've figured it out. At least what the problem is, if not the
solution. Thanks for setting me on the right path!

"My" ITrcQueueManager is an abstract interface. I have a .IDL which
defines its methods and classes which implement the interface in C++.
I have another class which defines the same methods with the same GUID
in C#, so that my .NET implementation can implement the same
interface.

The problem is, that the marshalling implemented by both is tied to
that abstract interface. Thus, when TrcNetSqlQm registers itself, it
overwrites the registry settings for TrcQm governing its mashalling.
:( The custom marshalling built in to .NET is incompatible with the
automatic marshalling done by my C++ implementations.

The question becomes, how to fix this? To state it succinctly, uf
they implement the same interface, they should have the same GUID, I
am told. But the marshalling of the two implementations is different
and should be different. AFAIK, COM gives me know way to do this for
a dual interface.

Is there a way to have both Dlls registered at the same time,
implementing the same interface with the same GUID and different
marshalling strategies? If not, what is the best alternative?

Thanks again,
JR

<snipped to save bandwidth>

Alexander Nickolov

unread,
Jan 22, 2003, 1:46:53 PM1/22/03
to
I hardly know .NET, but even I can tell you this - if the interface is
the same - don't define it twice - import it on the other platform
instead. Like for example define it in IDL and then import it through
the .NET COM Interop into C#. (I have no idea how this is done of
course... ask in the .NET groups)

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"J. R. Antley" <john_...@rhco.com> wrote in message news:70038508.03012...@posting.google.com...

J. R. Antley

unread,
Jan 22, 2003, 7:04:20 PM1/22/03
to
Um, yeah. Had I known the problem was related to interop in the first
place, I would have asked there *G*. It was only with Alexander's
help that I figured that out. Since I have now found the answer, I
will post my findings here and there. Hopefully somebody else will be
saved the three days it cost me *SIGH*.

Actually, Alexander, you are mistaken about implementing existing
ActiveX / COM interfaces in C#. The way to do it IS to redefine the
interface in C#, then make a class that implements the interface.
Specify for the INTERFACE (not the class) the proper Guid attribute
and ComImport.

I can see why you have to do it that way, but it certainly would be
nice if TlbImp (or some other tool) would generate an interface in C#
for an existing COM interface, as others have pointed out.

"By placing the [ComImport] attribute on the C# interface you're
telling the
runtime that the definition of this interface is defined elsewhere in
COM."

Thanks to David Stucki of Microsoft for this gem.

When you do this, the registration of the .NET implementation no
longer clobbers the marshalling in the registry with the new typelib
GUID.

To find the marshalling parameters for a given interface, search for
the GUID of that interface in using RegEdit.

Cheers,
JR

0 new messages