使用C ++互操作将非托管函数指针回调传递给托管代码

时间:2010-09-01 10:05:26

标签: c++ interop delegates unmanaged managed

我正在尝试将一些托管代码添加到现有的c ++ GUI应用程序中。我想得到一个功能回调工作...具体来说,我想将一个方法指针从UNMANAGED代码传递给MANAGED代码,并让托管代码调用回调。

我正在看这样的事情:

typedef int (__stdcall *ANSWERCB)(int);  //Delegate declaration

class UnmanagedObject
{
public:

 UnmanagedObject() {}
 int MethodD(int n) { return n; }
};

使用相应的托管类:

public delegate int CallbackDelegate(int i);

public class ManagedClass
{
    public ManagedClass() {}
    public void MethodD( CallbackDelegate cd ) { cd.Invoke( 5 ); }
}

问题在于,我不能为我的生活弄清楚如何从托管代码中实际调用它:

UnmanagedObject* obj = new UnmanagedObject();
ManagedLibrary::ManagedClass^ mc = gcnew ManagedLibrary::ManagedClass();
mc->MethodD( /* what do I pass here? */ );

我试过了:

ManagedLibrary::CallbackDelegate^ cd = gcnew CallbackDelegate(obj, &UnmanagedObject::MethodD);

但它会生成编译器错误“委托目标需要是指向成员函数的指针”。

任何互操作大师都能帮忙吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

问题从您的ANSWERCB函数指针声明开始。它实际上不适合调用MethodD()函数,这是该类的实例方法。首先使用本机C ++工作,需要一个成员函数指针。

从那里开始,使用托管代码可以减少问题,Marshal :: GetDelegateForFunctionPointer()可以满足您的需求。

答案 1 :(得分:0)

问题的一半是有问题的成员函数实际上与回调委托没有相同的签名。它需要一个函数指针本身。首先,您需要将UnmanagedClass更改为

class UnmanagedObject
{
public:
    UnmanagedObject() {} 
    int MethodD(int n) { return n; } 
};

我怀疑gcnew调用你只是错误的参数 - 即mem func ptr,然后是obj。