用于C++回调的C#委托

Val*_*dur 11 c# c++ delegates callback dllimport

我想我基本上已经理解了如何为回调编写c#delegates,但是这个让我很困惑.c ++定义如下:

typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam 
);
Run Code Online (Sandbox Code Playgroud)

我的c#方法是:

 unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
Run Code Online (Sandbox Code Playgroud)

虽然这似乎是不正确的,因为我得到一个PInvokeStackInbalance错误,这意味着我对委托的定义是错误的.

函数的其余参数是字符串或整数,这意味着它们不会导致错误,如果我只是传递一个IntPtr.Zero而不是委托(这意味着我指向一个不存在的回调函数)我得到一个AccessViolation错误,这也是有意义的.

我究竟做错了什么?

编辑:

完整的c ++功能是:

int
__stdcall
_Initialize (
const char*         FileName,
Callback            cbFunction,
int                 Code,
const char*         Name,
unsigned int        Option,
unsigned int        Option2
);
Run Code Online (Sandbox Code Playgroud)

我的c#版本是:

[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
Run Code Online (Sandbox Code Playgroud)

该函数是(用于测试)刚刚在控制台应用程序的主例程中调用:

static void Main(string[] args)
{
    CallbackDelegate del = new CallbackDelegate(onCallback);

    Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
    Console.Read();
}
Run Code Online (Sandbox Code Playgroud)

onCallback是:

static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

PInvokeStackInbalance在我调用的行上得到错误_Initialize,如果我传递一个IntPtr.Zero而不是委托,并将函数的定义更改为IntPtr而不是CallbackDelegate然后我得到一个AccessViolationException.

Way*_*ner 5

我将您的代码添加到当前项目中,在VS2012中我正在该项目中进行大量C#/ C ++互操作。虽然我讨厌使用“在我的机器上可以使用的软件”,但对我来说却很好。下面列出了我运行的代码,只是为了说明我没有做和根本的更改。

我的建议是,使用如下所示的_Initialize存根函数构建一个新的本机dll,并在可以控制界面的两侧时查看它是否有效。如果该方法有效,但真正的dll不起作用,则归结为本机端的编译器设置,或者它们是本机端的错误,并且在堆栈上踩踏。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在C#端,我在接口类中添加了声明:

 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);
Run Code Online (Sandbox Code Playgroud)

然后在我的主要内容中:

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));
Run Code Online (Sandbox Code Playgroud)


Pup*_*ppy 3

.NETlong是 64 位。C++long可能只有 32 位。请与编译该定义的 C++ 编译器检查其大小long