In this article, I demonstrate how to call a C++ function, set a callback function in C#, and output showcasing the successful callback from C++ to C#.
Let's see a simple code example here:
internal class CallbackfromCpp
{
public delegate void CallbackDelegate(string result);
[DllImport("CallBackC.dll", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi)]
public static extern int Add
(int a, int b, string input, CallbackDelegate callback);
public static void MyCallback(string result)
{
Console.WriteLine("Callback invoked from C++ with result: " + result);
}
public void RunAdd()
{
int res = Add(9, 8, "res", MyCallback);
Console.WriteLine("the result of Add function: " + res);
}
}
In class CallbackfromCpp
, we define a delegate, declare a function whose name is same as a function in CallBackC.dll. Then we set a function MyCallback
for the delegate with same signature list. It will print the parameter passed by its caller. Finally, let's see the entry method RunAdd
. It calls the Add
function with parameters (9, 8, "res", MyCallback)
and stores the return value in res
.
Run CallbackfromCpp.RunAdd()
and you'll see the output below:
Callback invoked from C++ with result: res
the result of Add function: 17
It's widely known that if you want to call C++ function in C#, you need a C++ DLL with the target function you want to use and then use the DllImport
attribute in a function declaration in your C# code. In this example, the function is Add
. This is how we get the second line in control panel. But for the first line, it's obviously from MyCallback
.
How is the MyCallback
function being called in C++? The third parameter in function, Add
, is CallbackFunction
type, we can see from the typedef
above the function signature. It's actually __stdcall
. So it's a pointer passed by the caller and Add
function will pass the parameter c
to the pointer. Then C# code will execute the delegate!
#include "CallBackC.h"
int Add(int a, int b,char *c, CallbackFunction callback) {
int result = a + b;
if (callback != nullptr) {
callback(c);
}
return result;
}
#pragma once
typedef void(__stdcall* CallbackFunction)(char* result);
extern "C" __declspec(dllimport) int Add(int a, int b,char *c, CallbackFunction callback);
History
- 14th December, 2023: Initial version