尽管功能设置正确,但DllImport __Internal无法正常工作

时间:2016-09-23 10:04:33

标签: c# c++ gcc mono pinvoke

使用嵌入式Mono,我试图在C#中执行一个非常简单的C函数。

这是C ++代码中的函数(在全局范围内):

extern "C"
{
    static int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

这是C#代码:

[DllImport("__Internal", EntryPoint="dllImportTest")]
public static extern int dllImportTest();

public void testCFunctions()
{
    int dllImport = dllImportTest();
    System.Console.Write("Got dllImport: " + dllImport + "\n");
}

这是我得到的错误:

System.EntryPointNotFoundException: dllImportTest
  at (wrapper managed-to-native) MonoGlue.ATestClass:dllImportTest ()
  at MonoGlue.ATestClass.testCFunctions () [0x0000a] in <9effaf2265b34fbcb9a10abd58c42ed7>:0 

我一直在看例子和类似问题,但我没看到出了什么问题。为了确保C函数不被优化,我在C ++代码中执行它 我甚至可以阻止内联,你可以看到。

然而,仍然没有运气。仍然有一些我不知道的东西。

1 个答案:

答案 0 :(得分:1)

由于它是静态的,因此dllImportTest函数没有出现在可执行文件中。无可否认,无论如何,全局命名空间中的静态函数在大多数情况下都没有意义。

所以取而代之:

extern "C"
{
    static int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

有了这个:

extern "C"
{
    int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

解决问题。

原因是通过在全局命名空间中创建一个函数static,外部编译单元变得无法访问,这使得C#也无法访问(我错误地认为这不会影响C#访问)。
这里的事情变得有点复杂,所以如果你想告诉自己,请继续阅读有关编译单元的内容。

如果您确实需要访问静态功能(无论在哪个命名空间中),我建议使用&#34;内部呼叫&#34;方法 - 如official mono example所示。它还有许多其他好处。