c++/cli pass (managed) delegate to unmanaged code

Yes, you want Marshal::GetFunctionPointerForDelegate(). Your code snippet is missing the managed function you’d want to call, I just made one up. You will also have to declare the managed delegate type and create an instance of it before you can get a function pointer. This worked well:

#include "stdafx.h"

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed(push, off)
typedef void (* UnmanagedSummer)(int arg);

void UnmanagedMethod(int a, int b, UnmanagedSummer sum)
{
    int result = a + b;
    sum(result);
}
#pragma managed(pop)

ref class Test {
    delegate void ManagedSummer(int arg);
public:
    static void Run() {
        Test^ t = gcnew Test();
        ManagedSummer^ managed = gcnew ManagedSummer(t, &Sum);
        IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(managed);
        UnmanagedSummer functionPointer = static_cast<UnmanagedSummer>(stubPointer.ToPointer());
        UnmanagedMethod(1, 2, functionPointer);
        GC::KeepAlive(managed);    // Important: ensure stub can't be collected while native code is running
        System::Diagnostics::Debug::Assert(t->summed == 3);
    }
    void Sum(int arg) {
        summed += arg;
    }
    int summed;
};

int main(array<System::String ^> ^args)
{
    Test::Run();
    return 0;
}

Leave a Comment