dsh*_*let 7 c# c++ delegates function-pointers
我正在尝试使用(C)第三方库,该库具有回调机制,缺少任何可能的方法来识别调用上下文.我的主要项目是C#,我的包装器是一个C++/CLI项目来调用C库API.
若要解决此问题,我正在尝试使用Marshal :: GetFUnctionPointerForDelegate.这是我的C#代码:
void Init(Handler Callback)
{
// Create a wrapper lambda in case Callback is a non-static method.
instance.CreateBuffers((x, y) => Callback(x, y));
}
Run Code Online (Sandbox Code Playgroud)
然后,在C++/CLI代码中:
void CreateBuffers(Handler^ Callback)
{
pinCallback = GCHandle::Alloc(Callback);
void (*callback)(int, int) = (void (__stdcall *)(int, int))Marshal::GetFunctionPointerForDelegate(Callback).ToPointer(),
// Use 'callback' in third party library...
}
Run Code Online (Sandbox Code Playgroud)
所有这些的问题是根据http://msdn.microsoft.com/en-us/library/367eeye0.aspx,来自Marshal :: GetFunctionPointerForDelegate的函数指针是一个stdcall函数,但我的C回调是cdecl.如何在这里获得cdecl兼容功能?
我认为实现这一目标的最简单方法是声明您的委托类型是C#,并使用UnmanagedFunctionPointer属性来指定调用约定.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate ...
Run Code Online (Sandbox Code Playgroud)
然后使您的C++/CLI代码接收普通的本机C++函数指针.您可以传递委托的实例,并且由于委托具有该属性,因此编组人员知道该怎么做.
这允许您跳过GetFunctionPointerForDelegate步骤.实际上,它允许您跳过C++/CLI层,但我希望您不想这样做.
只要非托管代码可以看到函数指针,请确保托管代码保留对委托的引用.如果你不这样做,那么垃圾收集器可能会从你下面拉出地毯,因为它看不到非托管代码所持有的引用.
当然,此主题已在此处讨论过.Hans Passant在这里有一个详细的答案,值得一读:从C#调用C DLL方法的正确方法
| 归档时间: |
|
| 查看次数: |
3344 次 |
| 最近记录: |