【问题标题】:How to pass this pointer as context parameter for callback in c#如何将此指针作为上下文参数传递给c#中的回调
【发布时间】:2016-08-25 18:54:30
【问题描述】:

C++ 中,通常将“this”指针传递给回调注册方法,以便回调将收到返回的 this 指针。我有一个第 3 方库,我正在尝试与使用此模式的 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 方法并在回调函数中重构它?

【问题讨论】:

  • OnCallback 是一个实例方法。已有的 this 引用有什么问题?
  • 已修复。 OnCallback 是静态的,因为它没有传递隐式的“this”指针。
  • 有道理。当 C 函数所期望的只是指向具有任何调用约定的 C 函数的指针时,不期望 C 函数能够正确调用 .NET 委托。
  • 这似乎行得通!

标签: c# interop


【解决方案1】:

呃,您要求的是互操作噩梦,尤其是因为您正在处理“黑盒”第三方 DLL。

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

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

然后存储你的委托

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

最后在调用C代码的时候传入delegate

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

我也不认为你真的需要弄乱 this 指针,除非你真的在回调中需要它,否则我会尝试传入 null。在 .Net 土地上编组和编组引用并重新使用它是不安全的。

【讨论】:

  • 实际上,我正在处理一个黑盒 .lib 文件,为此我创建了一个包装它的 dll。 .lib 具有创建未注册 COM 对象的函数。 COM 对象有一个回调注册方法的接口。
猜你喜欢
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2019-04-22
  • 2013-01-25
  • 1970-01-01
相关资源
最近更新 更多