我想从C ++非托管代码中调用C#委托。无参数委托工作正常,但带参数的委托崩溃了我的程序

时间:2010-07-30 18:39:39

标签: c# c++ pinvoke marshalling unmanaged

以下是来自unmanged dll的函数的代码。它接受一个函数指针作为参数,并简单地返回被调用函数返回的值。

extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)());
extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)())
{
    int r = pt2Func();
    return r;
}

在托管C#代码中,我使用委托调用上面的umanged函数。

  unsafe public delegate int mydelegate( );

    unsafe public int delFunc()
    {
             return 12;
    }

    mydelegate d = new mydelegate(delFunc);
    int re = callDelegate(d);
   [DllImport("cmxConnect.dll")]
    private unsafe static extern int callDelegate([MarshalAs(UnmanagedType.FunctionPtr)] mydelegate d);

这一切都很棒!!但是,如果我希望我的函数指针/委托接受参数,它会使程序崩溃。 因此,如果我按如下方式修改代码,程序崩溃。

修改了非托管c ++ -

extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)(int));
extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)(int))
{
    int r = pt2Func(7);
    return r;
}

修改后的C#代码 -

unsafe public delegate int mydelegate( int t);

        unsafe public int delFunc(int t)
        {
                 return 12;
        }

        mydelegate d = new mydelegate(delFunc);
        int re = callDelegate(d);

2 个答案:

答案 0 :(得分:3)

函数指针的调用约定是错误的。看起来像这样:

 int (__stdcall * pt2Func)(args...)

答案 1 :(得分:0)

所以这应该有效:

C ++ DLL:

extern "C" __declspec(dllexport) void __stdcall doWork(int worktodo, int(__stdcall *callbackfunc)(int));

C#代码:

delegate int del (int work);    

[DllImport(@"mydll")]
private static extern void doWork(int worktodo, del callback); 

int callbackFunc(int arg) {...} 

...

del d = new del(callbackFunc);
doWork(1000, d);