假设我有一个非托管类 Test :
class Test
{
public:
int SomeMethod(int a, bool b);
};
要创建一个新的Test实例,我会:
Test *test = new Test();
我的目标是嵌入Mono,以便托管代码可以在特定对象中调用非托管方法(如Test::SomeMethod
)。我通过将该对象的指针传递给托管方法来表示该对象,如下所示:
void *args[1];
args[0] = &test;
mono_runtime_invoke(init, NULL, args, NULL);
以下是调用的托管方法如下所示:
public static void Init(IntPtr test)
{
}
从这里开始,我该如何致电Test.SomeMethod
?
我考虑过使用CALLI
发出System.Reflection.Emit
指令,但我怎样才能引用指针test
(Init
的第一个参数)的对象是指?
我不想要使用DllImport
。
答案 0 :(得分:3)
您可能对CXXI感兴趣。它基于您的C ++头创建托管程序集,并允许您使用C ++对象,就像它们是普通的托管对象一样。
据我所知,它还没有完成,只适用于GCC编译的C ++代码。
答案 1 :(得分:0)
无法完成(或者至少不应该这样做)。
您正在尝试直接混合两个完全不同的执行环境 - DLLImport
存在的原因是允许编译器解决此问题。
在.NET中,您可以创建混合模式应用程序(C ++ / CLI),它允许托管代码和非托管代码共存于同一个二进制文件中(并相互调用),但由于您在谈论单声道,我假设选项已经结束。
像.NET这样的托管环境具有严格的类型规则,垃圾收集和其他功能,这些功能根本不适用于非托管代码和数据。
答案 2 :(得分:0)
如果您不想使用DllImport,可以使用内部呼叫。 请参阅https://github.com/mono/mono/blob/master/samples/embed/teste.c mono_add_internal_call()调用和test.cs文件中的C#代码。 这主要类似于DllImport,除了没有为您完成编组(C#代码中的字符串对象将在C代码中显示为MonoString *,而不是作为char *)。
在任何情况下,请注意您可以使用DllImport访问的函数和使用mono_add_internal_call()注册的函数指针都必须是C函数,而不是C ++成员方法。