[ACCEPTED]-Howto implement callback interface from unmanaged DLL to .net app?-managed
You don't need to use Marshal.GetFunctionPointerForDelegate(), the 14 P/Invoke marshaller does it automatically. You'll 13 need to declare a delegate on the C# side 12 whose signature is compatible with the function 11 pointer declaration on the C++ side. For 10 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 9 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 8 to get you started with it. There are a 7 million details that can get you into trouble, you 6 are bound to run into some of them. The 5 much more productive way to get this kind 4 of code going is writing a wrapper in the 3 C++/CLI language. That also lets you wrap 2 a C++ class, something you can't do with 1 P/Invoke. A decent tutorial is available here.
P/Invoke can handle marshaling a managed 19 delegate to a function pointer. So if you 18 expose API's that register a call back function 17 from your DLL and in C# pass a delegate 16 to that function.
There is an example on 15 MSDN of doing this with the EnumWindows function. In 14 that article be careful to pay attention 13 to the line in point 4 that states:
If, however, the 12 callback function can be invoked after 11 the call returns, the managed caller must 10 take steps to ensure that the delegate 9 remains uncollected until the callback function 8 finishes. For detailed information about 7 preventing garbage collection, see Interop 6 Marshaling with Platform Invoke.
What that 5 is saying is that you need to make sure 4 that your delegate isn't garbage collected 3 until after the managed code is done calling 2 it by either keeping a reference to it in 1 your code, or pinning it.
See Marshal.GetFunctionPointerForDelegate, which will give you a function pointer 2 for calling managed (i.e. C# code) from 1 unmanaged code.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.