我不是 100% 确定这是否是您正在寻找的。
在我们的例子中,我们有一个第三方 C Sdk,它为回调消息提供了几个钩子。回调调用在 C 代码中启动并期望调用 C 函数,但我们可以使用以下步骤将其挂钩到 C# 方法。(这段代码有点老了,可能有更简洁和现代的方法可以在较新的 C# 迭代中完成相同的任务)。
首先,我们在 C# 类中声明一个回调委托,与 SDK 期望的 C 函数指针的签名兼容。
例如,如果 C 代码期望回调具有以下签名的函数:
void DecCallBack(int nPort, void* pBuf, int nSize, FRAME_INFO *pInfo, int nReserved1, int reserved 2);
这是匹配的 C# 委托定义。请注意,“魔术”是由于以下UnmanagedFunctionPointer
属性而发生的:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void DecCallBack(int nPort, IntPtr pBuf, int nSize, ref FRAME_INFO frameInfo, int nReserved1, int nReserved2);
一旦我们有了这个,我们声明一个类型的类成员DecCallBack
,它将在我们的类中保存一个委托实例。
static DecCallBack _decodeCallBack = null;
接下来我们编写一个与委托签名兼容的处理程序方法。在这种情况下,我们将其命名为HandleDecData()
private static void HandleDecData(int nPort, IntPtr pBuf, int nSize, ref FRAME_INFO frameInfo, int nReserved1, int nReserved2) {
// Here we handle the callback, this code is being called from an external C library
}
接下来,在 C# 类的某个地方,我们需要初始化委托成员并挂钩我们的回调 Handler(在这种情况下它是静态方法HandleDecData()
_decodeCallBack += new DecCallBack(HandleDecData);
最后,我们将委托成员作为指向 C 的函数指针传递。在我们的例子中,第三方 SDK 有一个 CPlayM4_SetDecCallBack()
函数,该函数期望在调用回调时调用函数指针 - 我们可以安全地传递而是我们的班级。
if( !PlayM4_SetDecCallBack(channel, _decodeCallBack) )
throw new InvalidOperationException("Error setting DecCallBack");
我希望这是有帮助的。