Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 836
chrmue Avatar asked Jan 30 '10 12:01

chrmue


People also ask

How do you implement a callback in C#?

Callback by Delegate Delegate provides a way to pass a method as argument to other method. To create a Callback in C#, function address will be passed inside a variable. So, this can be achieved by using Delegate.

How do you implement callbacks?

To implement a callback functionCreate the managed callback function. The example declares a delegate type, called CallBack , which takes two arguments (hwnd and lparam). The first argument is a handle to the window; the second argument is application-defined.

How do you pass a parameter to a callback function in C#?

You could also create a (thread-static) context object, which stores your "state" (in this case, the index variable value), which you can access using a static property (say MyContext. Current ). Depends on the complexity of the context ... WCF uses something like this with OperationContext.

What is DLL callback function?

A callback function is code within a managed application that helps an unmanaged DLL function complete a task. Calls to a callback function pass indirectly from a managed application, through a DLL function, and back to the managed implementation.


1 Answers

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.

like image 104
Hans Passant Avatar answered Sep 28 '22 20:09

Hans Passant