preservesig flag will do the trick for you (see description of PreserveSigAttribute in 
MSDN for details on what it is good for). 

Also, there are usually "cil managed" flags instead of "native unmanaged" flags on 
pinvoke calls. I am not sure at the moment whether these make any difference.

I would recomend the signature of your function to be:

.method public static pinvokeimpl("UnmanEx.dll" cdecl) void SomeFunction() cil managed 
preservesig {}

-Jan

Il presente posting viene fornito "cos� come �", senza garanzie, e non conferisce 
alcun diritto.

-----Original Message-----
From: Cristian Diaconu [mailto:[EMAIL PROTECTED]] 
Sent: Thursday, April 18, 2002 3:51 AM
To: [EMAIL PROTECTED]
Subject: [DOTNET-ROTOR] System.Runtime.InteropServices.COMException - Is it something 
obvious?


I'm working on this scenario that's a bit convoluted (essentially a pretext to play:) 
) but I will boil it down to it's bare essentials:

I'm calling a C function (SomeFunction()) in a DLL (UnmanEx.dll) from msil. Here's the 
relevant code:

// CallUnmanEx.il
.module extern UnmanEx.dll
.method public static pinvokeimpl("UnmanEx.dll" cdecl) void SomeFunction() native 
unmanaged {}

.method static void func() il managed
{
    .maxstack 0
    call void SomeFunction()
    ret
}

extern "C"
__declspec(dllexport) void SomeFunction(void)
{}

This call sequence results in:
Unhandled Exception: System.Runtime.InteropServices.COMException
(0xCCCCCCCC): Exception from HRESULT: 0xCCCCCCCC.
   at UnmanagedException()
   at func()
   at main() in CallUnmanEx.il:line 51

The problem seems to be that the generated stub calling SomeFunction() expects some 
COM HRESULT to be returned in EAX. However, since UnmanEx.dll is compiled in DEBUG and 
SomeFunction() has no code, the value that's left in EAX is the value that the debug 
stack frame setup code has stored there while populating the stack with NOMANLAND's 
codes (which explains the 0xCCCCCCCC).

Obviously, if I replace SomeFunction() with
extern "C"
__declspec(dllexport) void SomeFunction(void)
{
    __asm mov eax, 0
}

everything returns to normal (or expected).

Now, I have some doubts I stumbled across a bug due to two reason:

1. The same behavior is visible in the commercial CLR - hmmm, what are the chances of 
that? 2. It's hard for me to see how, if this was a bug, it would not have been caught 
already - since it's a fairly obvious one.

On the other hand I've checked the specs and the ilasm reference and I can't see 
anything obvious wrong with my code, my only recourse being to submit it for public 
review (and the ensuing humiliation no doubt :) )

Thanks

Cristian

Reply via email to