none
Call back mechanism in C# with C++ DLL

    Question

  •  

    Hi , i have created an Delegate for a call back mechanism in C# it looks like this.

     

    C#

    public delegate void LogProc(StructureA objAppcontext,[MarshalAs(UnmanagedType.I4)] int level,[MarshalAs(UnmanagedType.LPWStr)] string thisFile,[MarshalAs(UnmanagedType.I4)] int thisLine,

    [MarshalAs(UnmanagedType.LPWStr)] StringBuilder logMessage);

     

    this C# delegate is passed to the C++ DLL by another method which is marshalled

     

    C++ DLL

    static void LogProc (StructureA * context, const int level, const WCHAR * thisFile, const int thisLine, const WCHAR* logMessage)

     

    when the call back function is called it invokes my C# method ie. LogProc, but still when it goes back to C++ DLL i am getting the following Error Message

     

    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.

     

    Can anybody help me out on this issue

    Tuesday, August 28, 2007 3:50 AM

Answers

  • THe CLR defaults to the _stdcall calling convention for callback delegates, but your C++ code probably defaults to _cdecl unless you've changed it globally. Try changing the typedef to

     

    typedef void (_stdcall *FunPtr)(INT32 x);

    Thursday, August 30, 2007 7:32 AM
    Moderator

All replies

  • If StructureA truly is a struct then you should make the first delegate parameter a ref parameter.

     

    Also make sure the calling conventions match on the managed and native side, using the UnmanagedFunctionPointer attribute if needed.

     

    Tuesday, August 28, 2007 7:14 AM
    Moderator
  • StructureA  is not a structure it is a class type.....

     

    Thanks for reply

    Tuesday, August 28, 2007 8:54 AM
  • Your last argument should be a String, not a StringBuilder.  But that wouldn't explain the RTC error.  The MarshalAs attributes don't do anything.  Sure about StructureA being a class?   Pass it with "ref" and see what happens.
    Tuesday, August 28, 2007 12:30 PM
    Moderator
  • Hi nobugz , till i get same error even after passing StructureA as ref......................

    Tuesday, August 28, 2007 1:55 PM
  •  

    So have you done anything to narrow down exactly what's causing the error? Like removing all parameters and then adding them back one by one until the error occurs (assuming you can control botht he C# and C++ code)?

     

    Wednesday, August 29, 2007 9:34 AM
    Moderator
  • There's not much left but the actual calling convention.  The default is StdCall on Windows and normally enforced by __declspec(dllexport).  But it could be __cdecl if you used a .def file to export the function.  Try CallingConvention.Cdecl in the DllImport attribute.
    Wednesday, August 29, 2007 9:45 AM
    Moderator
  • Yeah i tried removing all the parameters it calls my callback function and goes back to c++ dll without any error.

     

    i had created a delegate

     

    C#

    public delegate void LogProcMessgaeWrap(int intx);

    i pass this delegate function pointer to  the dll through another method,

     

    C++

    typedef void (*FunPtr)(INT32 x);

    FunPtr CallBack;

     

    I have assigned delegate pointer passed to C++ DLL to

    CallBack in C++,

    and invoke this .by

    CallBack(12)

     

    only if i pass a parameter i encounter following error

     

    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.

     

    i need to pass only WCHAR* type in my call back function , can any body help me out on  this issue.

    Wednesday, August 29, 2007 11:05 AM
  • THe CLR defaults to the _stdcall calling convention for callback delegates, but your C++ code probably defaults to _cdecl unless you've changed it globally. Try changing the typedef to

     

    typedef void (_stdcall *FunPtr)(INT32 x);

    Thursday, August 30, 2007 7:32 AM
    Moderator
  •  

    Thank You

     

    after changing to _stdcall it works fine

    Thursday, August 30, 2007 1:14 PM
  • THe CLR defaults to the _stdcall calling conversion for callback delegates, but your C++ code probably defaults to _cdecl unless you've changed it globally. Try changing the typedef to

     

    typedef void (_stdcall *FunPtr)(INT32 x);


    Thanks very much! Could you give more explanation on it? I'm a beginner.
    Saturday, August 28, 2010 11:26 PM