如何将此指针作为c#中回调的上下文参数传递

时间:2016-08-25 18:54:30

标签: c# interop

C ++ 中,将'this'指针传递给回调注册方法是很常见的,这样回调就会收到这个指针。我有一个第三方库,我试图与使用此模式的 C#进行互操作。

实施例

typedef HRESULT (WINAPI PFNCALLBACK*)(CALLBACKDATA *data, void *context);

HRESULT SetCallback (PFNCALLBACK *callback, void *context);

我已经为回调函数定义了一个委托:

public delegate int Callback(IntPtr context, CallbackData sample);

并调用SetCallback函数

void SetupCallback()
{
  // My stab at passing the this pointer as context for the callback
  IntPtr pThis = GCHandle.ToIntPtr(GCHandle.Alloc(this));
  hr = obj.SetCallback(OnCallback, pThis);
}

public static int OnCallback(CallbackData data, IntPtr context)
{
   // HOW do I reconstitute the This pointer from the context parameter
}

我的问题是如何将 C#'this'指针传递给SetCallback方法并在回调函数中重新构建它?

1 个答案:

答案 0 :(得分:1)

呃,你要求一个互操作的噩梦,特别是因为你正在处理一个“黑匣子”第三方DLL。

话虽如此,从理论上说这应该可以通过利用 UnmanagedFunctionPointer属性。

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int Callback(IntPtr context, CallbackData sample);

然后存储你的代表

static Callback _someCallBack = null;
_someCallBack += new Callback(OnCallback);

最后在调用C代码时传入委托

IntPtr pThis = GCHandle.ToIntPtr(GCHandle.Alloc(this));
hr = obj.SetCallback(_someCallBack, pThis);

我也不认为你真的需要弄乱这个指针,除非你真的需要它在回调老实说我会尝试传入null。在.Net土地上进行编组和编组参考并重新使用它是不安全的。