Re: Why error?




"Yu Wang via .NET 247" <anonymous@xxxxxxxxxxxxx> wrote in message
news:etkXNRRKFHA.3420@xxxxxxxxxxxxxxxxxxxxxxx
>I am trying to test the callback function between C# and C++. I tried the
>sample code from MSDN (EnumWindows one), it worked. Then I tried mine:
>
> //C++
> typedef int (*CallBackFunc)(int a1, int a2);
>
> __declspec(dllexport) int InterOpTest(CallBackFunc func, int a1, int a2)
> {
> int j;
> j=func(a1, a2); //Line 4
> return j; //Line 5
> } //Line 6
>
> //C#
> public static int Add(int a1, int a2)
> {
> int a=a1+a2;
> return a;
> }
>
> public delegate int CallBack(int a1, int a2);
> [DllImport("test.dll")]
> public unsafe static extern int InterOpTest(CallBack func, int a1, int
> a2);
>
> public void Test()
> {
> int b1, b2;
> b1=b2=2;
> CallBack myCallBack = new CallBack(Add);
> int result=InterOpTest(myCallBack, b1, b2);
> }
>
> During dubugging, when the program runs to the end of the function "Add"
> (that is, after "return a"), an error window said:
>
> In C++ code
> Line 4
> Run-Time Check Failure #0 - The value of ESP was not properly saved across
> a function call. This is usually a result of calling a function declared
> with one calling convention with a function pointer declared with a
> different calling convention.
>
> If I ignore it, then a same error window pop up except that the error is
> on Line 6.
>
> What does that mean?
>
> Thanks.
>
> --------------------------------
> From: Yu Wang
>
> -----------------------
> Posted by a user from .NET 247 (http://www.dotnet247.com/)
>
> <Id>VHMkt26OZUyxS8pUNEGS+Q==</Id>

Your callback declaration:

typedef int (*CallBackFunc)(int a1, int a2);

should use stdcall calling convention:

typedef int (__stdcall *CallBackFunc)(int a1, int a2);

By default .NET uses __stdcall for functions and callbacks when marshaled to
native code though PInvoke, the default behavior for functions can be
changed by applying the CallingConventionAttribute, however, this default
cannot be changed for callbacks.

Note: v2.0 will make it possible to change this behavior for callbacks.


Willy.



.



Relevant Pages

  • Re: [patch 1/7] Immediate Values - Architecture Independent Code
    ... static unsigned int stopmachine_num_threads; ... * help our sisters onto their CPUs. ... all the other CPUs will execute the callback concurrently. ...
    (Linux-Kernel)
  • Re: Trying to use a legacy C function from DLL in managed code
    ... /* LINGO DLL definitions header ... This is usually done by passing it through the pUserData parameter (for example make a GCHandle and cast in the callback), but since .NET does runtime codegen this is unnecessary. ... int FormMain::SolverCallback ... if (dBestIP < *pdBestObjective) ...
    (microsoft.public.dotnet.framework.clr)
  • Re: function pointer help!
    ... //the return void and input prameters are defined in the manual... ... void MyProjectView::CallHandler(int,unsigned int, unsigned int, void*) ... You are attempting to use a C++ member function as the callback, but the callback is defined in terms or C, not C++. ... The underlying problem is that C++ functions receive a hidden parameter, the 'this' pointer, so their signature is incompatible with C definitions. ...
    (microsoft.public.vc.mfc)
  • Re: communicating through callback
    ... > and it sends the data I want to the callback function. ... context pointer that is then passed into the callback function ... typedef int (handle h, void * context); ...
    (comp.lang.c)
  • Re: Marshal callback containing unsigned char * in signature
    ... It is possible to change the calling convention for a callback to __cdecl, ... This is a third party dll that I'm ...
    (microsoft.public.dotnet.framework.interop)

Quantcast