c++/cli 将(托管)委托传递给非托管代码 [英] c++/cli pass (managed) delegate to unmanaged code
问题描述
如何将函数指针从托管 C++ (C++/CLI) 传递给非托管方法?我读了几篇文章,例如 这篇来自 MSDN,但它描述了两个不同的程序集,而我只想要一个.
How do I pass a function pointer from managed C++ (C++/CLI) to an unmanaged method? I read a few articles, like this one from MSDN, but it describes two different assemblies, while I want only one.
这是我的代码:
1) 标头 (MyInterop.ManagedCppLib.h):
1) Header (MyInterop.ManagedCppLib.h):
#pragma once
using namespace System;
namespace MyInterop { namespace ManagedCppLib {
public ref class MyManagedClass
{
public:
void DoSomething();
};
}}
2) CPP 代码 (MyInterop.ManagedCppLib.cpp)
2) CPP Code (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
方法,但无法编译.
I tried creating my managed delegate and then I tried to use Marshal::GetFunctionPointerForDelegate
method, but I couldn't compile.
推荐答案
是的,你想要 Marshal::GetFunctionPointerForDelegate().您的代码片段缺少您要调用的托管函数,我只是编造了一个.您还必须声明托管委托类型并创建它的实例,然后才能获得函数指针.这很好用:
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;
}
这篇关于c++/cli 将(托管)委托传递给非托管代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!