访问传递给本机 dll 的回调 c# 中的托管的对象

标签: dll C#
发布时间: 2013/12/4 23:37:37
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我想将一个 C# 回调函数传递到本机 dll。它正常工作,但我找不到的方式来访问父对象的回调方法。这里是一个代码,演示了想做什么:

class MyForm: Form {
  public delegate void CallbackDelegate(IntPtr thisPtr);

  [DllImport("mylib.dll", CallingConvention = CallingConvention.StdCall)]
  public static extern void Test(CallbackDelegate callback);

  int Field;

  static void Callback(IntPtr thisPtr)
  {
      // I need to reference class field Field here.
      MyForm thisObject = ?MagicMethod?(thisPtr);

      thisObject.Field = 10;
  }

  void CallExternalMethod()
  {
      Test(Callback);
  }
}

我试过的指针 this ,但有以下例外: 对象包含非基元或非本机数据。。我大概应该提及的父对象是 WindowsForms 窗体。

更新

Dll 用 delphi 编写和测试函数的签名如下所示:

type
  TCallback = procedure of object; stdcall;

procedure Test(Callback: TCallback); stdcall;

当我试图获取指向类的指针,用下面的代码时,我收到上面的错误消息:

var ptr = GCHandle.Alloc(this, GCHandleType.Pinned).AddrOfPinnedObject();

解决方法 1:

你是在想这个。C# 编组将创建一个 thunk 围绕您的委托。不,你必须尝试这样做。

德尔福一边写它像这样:

type
  TCallback = procedure; stdcall;

只需删除 of object

在 C# 一边您的委托是:

public delegate void CallbackDelegate();

您对您的代理使用的方法如下所示:

void Callback()
{
    // an instance method, so *this* is available
}

然后你调用到本机代码中像这样:

void CallExternalMethod()
{
    Test(Callback);
}

所以,让我们都放在一起。德尔福一边你可以编写:

library MyLib;

type
  TCallback = procedure; stdcall;

procedure Test(Callback: TCallback); stdcall;
begin
  Callback;
end;

exports
  Test;

begin
end.

与在 C# 边:

class MyForm: Form {
    public delegate void CallbackDelegate();

    [DllImport("mylib.dll")]
    public static extern void Test(CallbackDelegate callback);

    int Field;

    static void Callback()
    {
        Field = 10;
    }

    void CallExternalMethod()
    {
        Field = 0;
        Test(Callback);
        Debug.Assert(Field == 10);
    }
}
赞助商