Howto implement callback interface from unmanaged DLL to .net app?

前端 未结 4 1826
终归单人心
终归单人心 2020-11-27 04:54

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

4条回答
  •  暖寄归人
    2020-11-27 05:27

    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();
    }
    

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

    That's enough to get you started with it. There are a million details that can get you into trouble, you are bound to run into some of them. The much more productive way to get this kind of code going is writing a wrapper in the C++/CLI language. That also lets you wrap a C++ class, something you can't do with P/Invoke. A decent tutorial is available here.

提交回复
热议问题