HOWTO从非托管DLL到.NET应用程序实现回调接口?

问题描述:

在我的下一个项目,我想实现℃,已有code的GUI ++。
我的计划是在DLL来包装C ++的一部分,并落实在C#中的GUI。我的问题是,我不知道如何实现从非托管DLL回调到manged C#code。我已经做了在C#中的一些发展,但之间的接口托管和非托管code是新的我。任何人都可以给我一些提示或阅读提示或一个简单的例子开始?不幸的是我找不到任何有用的。

in my next project I want to implement a GUI for already existing code in C++. My plan is to wrap the C++ part in a DLL and to implement the GUI in C#. My problem is that I don't know how to implement a callback from the unmanaged DLL into the manged C# code. I've already done some development in C# but the interfacing between managed and unmanaged code is new to me. Can anybody give me some hints or reading tips or a simple example to start from? Unfortunatly I could not find anything helpful.

您不需要使用Marshal.GetFunctionPointerForDelegate(),在P / Invoke的编组将自动进行。你需要声明的C#方的签名是在C ++侧的函数指针声明兼容的委托。例如:

You don't need to use Marshal.GetFunctionPointerForDelegate(), the P/Invoke marshaller does it automatically. You'll need to declare a delegate on the C# side whose signature is compatible with the function pointer declaration on the C++ side. For example:

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 ++ code:

And the corresponding C++ code used to create the unmanaged DLL:

#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");
}

这足以让你开始吧。有100万的细节,可以让你陷入困境,你一定会碰到一些人。在更高效的方式来获得这样的code会被写在C ++ / CLI语言的包装。这也可以让你换一个C ++类,有些东西你不能用的P / Invoke做。一个体面的教程可以在这里找到。