一尘不染

如何实现从非托管DLL到.net应用程序的回调接口?

c#

在我的下一个项目中,我想为C 中已经存在的代码实现GUI。我的计划是将C
部分包装在DLL中,并在C#中实现GUI。我的问题是我不知道如何实现从非托管DLL到托管C#代码的回调。我已经用C#进行了一些开发,但是托管代码和非托管代码之间的接口对我来说是新的。任何人都可以给我一些提示或阅读提示或一个简单的示例作为开始吗?不幸的是,我找不到任何帮助。


阅读 381

收藏
2020-05-19

共1个答案

一尘不染

您不需要使用Marshal.GetFunctionPointerForDelegate(),P /
Invoke编组器会自动执行此操作。您需要在C#端声明一个委托,该委托的签名与C ++端的函数指针声明兼容。例如:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

class UnManagedInterop {
  private delegate int Callback(string text);
  private Callback mInstance;   // Ensure it doesn't get garbage collected

  public UnManagedInterop() {
    mInstance = new Callback(Handler);
    SetCallback(mInstance);
  }
  public void Test() {
    TestCallback();
  }

  private int Handler(string text) {
    // Do something...
    Console.WriteLine(text);
    return 42;
  }
  [DllImport("cpptemp1.dll")]
  private static extern void SetCallback(Callback fn);
  [DllImport("cpptemp1.dll")]
  private static extern void TestCallback();
}

以及用于创建非托管DLL的相应C ++代码:

#include "stdafx.h"

typedef int (__stdcall * Callback)(const char* text);

Callback Handler = 0;

extern "C" __declspec(dllexport)
void __stdcall SetCallback(Callback handler) {
  Handler = handler;
}

extern "C" __declspec(dllexport)
void __stdcall TestCallback() {
  int retval = Handler("hello world");
}

这足以让您开始使用它。一百万个细节可能使您陷入困境,您一定会遇到其中一些。使这种代码运行的更有效的方法是用C /
CLI语言编写包装器。这也使您可以包装C
类,而P /
Invoke无法做到这一点。此处提供了不错的教程

2020-05-19