C# delegate for C++ callback

前端 未结 3 1032
北恋
北恋 2021-01-04 13:02

I think I have basically understood how to write c# delegates for callbacks, but this one is confusing me. The c++ definition is as follows:

typedef int (__s         


        
相关标签:
3条回答
  • 2021-01-04 13:17
    [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
    unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
    

    If .NET assumes cdecl instead of stdcall, your stack will most assuredly be hosed.

    0 讨论(0)
  • 2021-01-04 13:30

    A .NET long is 64bits. A C++ long may be just 32bits. Check with the C++ compiler which compiled that definition as to what size it's longs are.

    0 讨论(0)
  • 2021-01-04 13:36

    I added your code to my current project where I'm doing a lot of C#/C++ interop in VS2012. And while I hate to use the "it worked on my machine", it worked fine for me. The code as I ran it is listed out below just to illustrate that I didn't make and fundamental changes.

    My suggestion is that you build a new native dll with a stub function for _Initialize such as below and see if it works when you can control both sides of the interface. If that works but the real dll doesn't, it comes down to either compiler settings on the native side or their is a bug on the native side and it is stomping on the stack.

    extern "C" {
    
        typedef int (__stdcall* Callback)(long lCode,long lParamSize,void* pParam );
    
        TRADITIONALDLL_API int __stdcall _Initialize (const char* FileName,Callback cbFunction, int                 Code,
                                    const char*         Name,unsigned int        Option,unsigned int        Option2)
        {
            cbFunction(0, 0, nullptr);
            return 0;
        }
    }
    

    On the C# side, I added the declarations to my interface class:

     public delegate int CallbackDelegate(int lCode, int lParamSize, IntPtr pParam);
    
     [DllImport("XXX.dll", CallingConvention = CallingConvention.StdCall)]
     public static extern int _Initialize(string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
    

    And then in my main:

    private int onCallback(int lCode, int lParamSize, IntPtr pParam)
    {
           return 0;
    }
    XXXInterface.CallbackDelegate del = new XXXInterface.CallbackDelegate(onCallback);
    
    Console.Write(XXXInterface._Initialize("SomeFile.dat", del, 1000, "", 0, 4));
    
    0 讨论(0)
提交回复
热议问题