2010-06-04 194 views
23

如何将托管C++(C++/CLI)的函数指针传递给非托管方法?我读了几篇文章,如this one from MSDN,但它描述了两个不同的程序集,而我只需要一个。C++/cli将托管代码传递给非托管代码

这是我的代码:

1)报头(MyInterop.ManagedCppLib.h):

#pragma once 

using namespace System; 

namespace MyInterop { namespace ManagedCppLib { 

    public ref class MyManagedClass 
    { 
    public: 
     void DoSomething(); 
    }; 
}} 

2)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??? */); 
} 

我尝试创建我的托管代理,然后尝试使用Marshal::GetFunctionPointerForDelegate方法,但我无法编译。

+0

请问您可以发布代码,其中您使用GetFunctionPointerForDelegate? – Simon 2010-06-04 08:21:40

回答

37

是的,你想要Marshal :: GetFunctionPointerForDelegate()。你的代码段缺少你想要调用的托管函数,我只做了一个。您还必须声明托管委托类型并在获取函数指针之前创建它的一个实例。这工作得很好:

#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; 
} 
+0

这个额外的演员是“缺失的链接”:-)谢谢! – 2010-06-06 15:39:33