マネージC++(C++/CLI)からアンマネージメソッドに関数ポインターを渡すにはどうすればよいですか? これはMSDNからのもの のようないくつかの記事を読みましたが、2つの異なるアセンブリについて説明していますが、1つだけが必要です。
これが私のコードです:
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
メソッドを使用しようとしましたが、コンパイルできませんでした。
はい、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;
}