c ++ / cli pass (gerenciado) delegar para código não gerenciado

Como faço para passar um ponteiro de function do C ++ (C ++ / CLI) gerenciado para um método não gerenciado? Eu li alguns artigos, como este do MSDN , mas ele descreve dois conjuntos diferentes, enquanto eu quero apenas um.

Aqui está o meu código:

1) Cabeçalho (MyInterop.ManagedCppLib.h):

#pragma once using namespace System; namespace MyInterop { namespace ManagedCppLib { public ref class MyManagedClass { public: void DoSomething(); }; }} 

2) Código CPP (MyInterop.ManagedCppLib.cpp)

 #include "stdafx.h" #include "MyInterop.ManagedCppLib.h" #pragma unmanaged void UnmanagedMethod(int a, int b, void (*sum)(const int)) { int result = a + b; sum(result); } #pragma managed void MyInterop::ManagedCppLib::MyManagedClass::DoSomething() { System::Console::WriteLine("hello from managed C++"); UnmanagedMethod(3, 7, /* ANY IDEA??? */); } 

Eu tentei criar meu delegado gerenciado e tentei usar o método Marshal::GetFunctionPointerForDelegate , mas não consegui compilar.

    Sim, você quer Marshal :: GetFunctionPointerForDelegate (). Seu snippet de código está sem a function gerenciada que você deseja chamar, acabei de criar uma. Você também terá que declarar o tipo de delegado gerenciado e criar uma instância dele antes de poder obter um ponteiro de function. Isso funcionou bem:

     #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(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 ^args) { Test::Run(); return 0; }