从托管代码调用非托管方法

时间:2012-02-29 11:13:30

标签: c# c++ mono cil reflection.emit

假设我有一个非托管类 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指令,但我怎样才能引用指针testInit的第一个参数)的对象是指?

想要使用DllImport

3 个答案:

答案 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 ++成员方法。