【发布时间】:2017-10-19 07:41:01
【问题描述】:
我正在尝试将委托编组为函数指针。委托的返回类型是字符串数组,而函数指针的返回类型是char**
下面的代码抛出了无效的托管/非托管类型组合异常。我该如何解决?
// unmanaged code
typedef char** (*MyFuncPtr)(void);
class __declspec(dllexport) MyUnmanagedClass{
private:
MyFuncPtr mFunPtr
public:
MyUnmanagedClass(MyFuncPtr funPtr)
{
mFunPtr = funPtr;
}
char* Func1()
{
// callback
mFunPtr();
return "something";
}
};
// managed wrapper (CLI)
public delegate cli::array<String^>^ MyDelegate();
public class MyCliClass{
private:
MyDelegate mDel;
public:
MyCliClass(MyDelegate del)
{
mDel = del;
}
String^ Func2()
{
MyFuncPtr funPtr = static_cast<MyFuncPtr>(Marshal::GetFunctionPointerForDelegate(mDel).ToPointer());
MyUnmanagedClass* muc = new MyUnmanagedClass(funPtr);
char* retValPtr = muc->Func1();
return context->marshal_as<String^>(retValPtr);
}
};
// managed client (C#)
class Program
{
static void Main( string[] args )
{
MyCliClass mcc = new MyCliClass(Func3);
mcc.Func2();
}
static string[] Func3()
{
return new[] { "Some 1", "Some 2" };
}
}
【问题讨论】:
-
无法从 C 或 C++ 程序可靠地调用该函数。调用者无法知道返回的数组中有多少元素以及是否需要释放字符串和数组的存储空间。例外只是告诉您编组器也不知道。它不能知道。你必须重新考虑这一点。
-
在这种情况下,我还有什么其他选择可以实现这一目标?
-
为自己设定一个避免
GetFunctionPointerForDelegate的目标。 C++/CLI 不需要它,因为 C++/CLI 代码可以调用 C++ 和 C# 函数并直接访问 C++ 和 C# 对象。因此,您需要一个具有正确调用签名的 C++/CLI 函数,这样您就可以获取指向它的指针并立即获得正确的类型(无需强制转换!)。在该函数中,您可以访问 C# 对象、调用委托,以及您需要做的任何事情。 -
我不明白,您可以提供一个快速示例吗?