2013-04-09 82 views
4

在Native C dll中有以下代码。使用C#中的函数指针调用C++函数作为参数

typedef void CallbackType(INT32 param1, INT32 param2); 

NATIVE_API void RegisterEventCallBack(CallbackType *callBackFunction); 


//INT32 is defined as below: 

typedef signed int   INT32, *PINT32; 

我必须从我的C#代码中调用此方法。在stackflow以下提供一些解决方案之后,我尝试这样做:

委托声明:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
public delegate void CallbackType(Int32 param1, Int32 param2); 

方式进口报关:

[DllImport("EtIPAdapter.dll")] 
public static extern void RegisterEventCallBack([MarshalAs(UnmanagedType.FunctionPtr)]CallbackType callbackFunc); 

呼叫:

RegisterEventCallBack(ReceivedData); 

private static void ReceivedData(Int32 param1, Int32 param2) 
{ 
    //Do something 
} 
通过传递函数指针,我使用 GetFunctionPointerFromDelegate(ReceivedDataDelegate)

A call to PInvoke function 'RegisterEventCallBack' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我也试过:

但是,这并不工作,我碰到下面的错误。但是这也会导致相同的错误。

错误指出签名不匹配,但我没有看到任何明显的签名不匹配。请帮忙。

+0

你可以在链接中试试以下声明: http://stackoverflow.com/a/9855516/2253250也应该检查一下函数原型是否正确? http://www.nirsoft.net/utils/dll_export_viewer.html可以使用DllExport Viewer。 – Gencebay 2013-04-09 10:20:14

+1

如何定义“NATIVE_API”宏?我认为问题出在你的RegisterEventCallBack函数的管理声明上,而不是回调委托。你使用正确的调用约定吗?当它的回调参数使用'cdecl'时,'RegisterEventCallBack'使用'stdcall'(DllImport'的默认值)似乎很奇怪。 – shambulator 2013-04-09 10:23:47

回答

1

请在执行DLLImport时检查调用约定 - 默认为Winapi/StdCall。
另外,在应用程序的生命周期中,必须在托管代码内保留对委托的引用,因为垃圾收集器会在一段时间后删除委托,因为垃圾收集器只能对托管代码内的引用进行计数。我通常保持对委托的引用,作为设置委托的类的静态属性。

+0

谢谢。更改DLLImport命名约定为“cdecl”工作。 [DllImport(“EtIPAdapter.dll”,CallingConvention = CallingConvention.Cdecl)] public static extern void RegisterEventCallBack([MarshalAs(UnmanagedType.FunctionPtr)] LogEventCallbackType pfnLogEvent); – Nirdesh 2013-04-09 10:48:15