【问题标题】:DllImport __Internal not working despite correct function setup尽管功能设置正确,DllImport __Internal 仍无法正常工作
【发布时间】:2016-09-23 10:04:32
【问题描述】:

使用嵌入式 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++ 代码中执行它。
如您所见,我什至阻止内联。

但是,仍然没有运气。一定还有我遗漏的东西。

【问题讨论】:

  • 好像找不到dll本身。您是否确保您的应用程序可以找到该 dll? msdn.microsoft.com/en-us/library/…
  • "__Internal" 表示它不是外部DLL,而是嵌入C#的环境:)
  • 不,没有交易。我尝试使用 mys、mys.so 等。它们都导致 System.DllNotFoundException 。 __Internal 必须是正确的东西,但是它没有找到函数。
  • 好吧,给我们看看链接器的 .map 文件,这样我们就可以看到函数的真实名称是什么样的了。

标签: c# c++ gcc mono pinvoke


【解决方案1】:

原来 dllImportTest 函数没有出现在可执行文件中,因为它是静态的。诚然,在大多数情况下,全局命名空间中的静态函数几乎没有意义。

所以替换这个:

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

有了这个:

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

解决问题。

原因是通过将全局命名空间中的函数设为静态,外部编译单元无法访问它,这也使得 C# 也无法访问它(我错误地认为这不会影响 C# 访问)。
事情在这里变得有点复杂,所以如果你想了解自己,请继续阅读编译单元。

如果您确实需要访问静态函数(无论在哪个命名空间中),我推荐使用“内部调用”方法 - 如 official mono example 中所示。它还有许多其他好处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多