65.9K
CodeProject is changing. Read more.
Home

Interoperability between C++ and C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (8 votes)

Dec 13, 2023

CPOL

1 min read

viewsIcon

11594

Demo of how C++ and C# interoperate

Let's see a simple code example here:

    internal class CallbackfromCpp
    {
        // Delegate definition for the callback function

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

        // Callback function in C#
        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!

// CallBackC.cpp
#include "CallBackC.h"

int Add(int a, int b,char *c, CallbackFunction callback) {
    int result = a + b;

    // Invoke the callback function
    if (callback != nullptr) {
        callback(c);
    }

    return result;
}

// CallBackC.h
#pragma once

// Define a callback function signature
typedef void(__stdcall* CallbackFunction)(char* result);

// Export the Add function directly
extern "C" __declspec(dllimport) int Add(int a, int b,char *c, CallbackFunction callback);

History

  • 14th December, 2023: Initial version