CLR Host - how to execute functions with arbitrary method signature

303 views Asked by At

I've a managed C# test DLL and I want to call its functions from my unmanaged C++ code.

The problem is that I can't find an example that shows how to call arbitrary functions from my c++ code, I could only get the ICLRRuntimeHost::ExecuteInDefaultAppDomain working, but this function does use a predefined method signature.

Question

I'm able to execuete the ShowMsg function from my C# DLL but I can't find out how to call methods with other signatures than int(int). Can someone please help me with that?

C++ Code

// interface definitions of functions from c# dll
typedef int (*TestCallbackPtr)(std::wstring info, int value1, double value2);
typedef int (*TestFunctionPtr)(std::wstring string1, int int1, double double1, TestCallbackPtr callback);

// path of my c# dll
auto pathDll = L"..." 

void RunTest()
{
    ICLRMetaHost* clrMetaHost = NULL;
    ICLRRuntimeInfo* clrRuntimeInfo = NULL;
    ICLRRuntimeHost* clrRuntimeHost = NULL;
    
    // loading the data above is excluded for simplicity!
    // ... 
    
    // -------------
    // Test 1: run ShowMsg => WORKING
    // -------------
    
    DWORD pReturnValue;
    HRESULT result = clrRuntimeHost->ExecuteInDefaultAppDomain(pathDll, L"Test.Managed", L"ShowMsg", L"Hello from C++", &pReturnValue);
    
    // -------------
    // Test 2: run TestFunction
    // -------------
    
    TestCallbackPtr callback = [](std::wstring info, int value1, double value2) {
        return 21;
    };
    TestFunctionPtr function = NULL;
    
    // how to continue? how can I execute the function here and assign my local function pointer so that following will work:
    // (*function)(L"Test", 45, 1.23, callback);
}

C# Code

namespace Test
{    
    public class Managed
    {
        public static int ShowMsg(string msg)
        {
            MessageBox.Show(msg);
            return 0;
        }

        public delegate int TestCallback([MarshalAs(UnmanagedType.LPWStr)] string info, int value1, double value2);

        public static int TestFunction(
            [MarshalAs(UnmanagedType.LPWStr)] string string1, 
            int int1,
            double double1,
            TestCallback callback)
        {
            string info = $"string1 = {string1} | int1 = {int1} | double1 = {double1}";
            int returnValue = callback(info, 5, 10.34);
            return returnValue;
        }
    }   
}
0

There are 0 answers