【问题标题】:call C++ shared library from C# .net core console in Linux在 Linux 中从 C# .net 核心控制台调用 C++ 共享库
【发布时间】:2017-08-09 08:14:24
【问题描述】:

我正在编写一个示例以使用 c# 代码调用 c++ 共享库中的某些函数。环境为 Ubuntu 16.04 和 .NET Core 2.0。

       class Program
       {
           [DllImport("libc.so.6")]
            private static extern int getpid();           
           [DllImport("/home/xxx/invoke/hi.so")]
            private static extern int Sayhi();

           static void Main(string[] args)
           {
            int pid= getpid();
            Console.WriteLine(pid);
            Console.WriteLine("Hello World!");
            int status= Sayhi();
            Console.WriteLine(status);

            }
        }

cpp:

#include <iostream>
using namespace std;
int Sayhi(){
cout<<"hello world from cpp!"<<endl;
return 1;
}

如果我运行 c# 代码,我会收到错误消息:

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'Sayhi' in DLL '/home/xxx/invoke/hi.so'.
   at invoke.Program.Sayhi()
   at invoke.Program.Main(String[] args) in /home/xxx/invoke/Program.cs:line 17

我认为编译器可能会更改函数的名称,因此无法找到它。如何解决?

【问题讨论】:

标签: c# .net-core pinvoke


【解决方案1】:

您需要将您的 C++ 函数标记为 extern "C",以便 .NET Core 运行时可以找到函数名称。

【讨论】:

  • 如果这个答案解决了您的问题,请考虑accepting the answer
  • @Martin Ullrich 如果我没有源代码。有什么办法可以强制编译器不要破坏名称。我知道如何在 Windows 中做到这一点,但不知道 linux
  • 使用 C 命名约定从符号表中读取名称。但您也可以在 DllImport's EntryPoint property 中指定完全损坏的名称
  • 如果你没有源代码,你将如何编译不同选项的库?
  • 我看到大多数 C++ 类库现在只对类库函数使用 extern。因此,如果我们不能仅从 .Net Core 调用 extern 方法,那么这对于现有的 dll 来说是一个问题,无需修改源代码。此外,还有一个问题,所有 C++ 标准库都不支持 extern "C"。如果有从.Net核心调用外部函数的任何解决方案,请在此处提及。
猜你喜欢
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多