在 ubuntu 操作系统中从单声道 P/Invoke g++

Posted

技术标签:

【中文标题】在 ubuntu 操作系统中从单声道 P/Invoke g++【英文标题】:P/Invoke g++ from mono in ubuntu OS 【发布时间】:2011-05-05 17:22:11 【问题描述】:

是否可以在 Ubuntu 中从 mono 调用 g++ 可执行文件的函数?请注意,在 Ubuntu 操作系统中编译的 C++ 和 C# 代码。

C++应用源码:

#include <stdlib.h>

static int32_t Sum(int32_t a, int32_t b)
    return a + b;

/*
 * 
 */
int main(int argc, char** argv) 
    return (EXIT_SUCCESS);

C#单声道应用源码:

using System;
using System.Runtime.InteropServices;

namespace MonoCsTest

 class MainClass
 

  [DllImport("/home/.../MonoCsTest/bin/Debug/testcpp")]  
  public static extern Int32 Sum(Int32 a, Int32 b);

  public static void Main (string[] args)
  
   Console.WriteLine (" 5 + 6 = " + Sum(5,6));
  
 

这会抛出DllNotFoundException

【问题讨论】:

我有一个共享库 (.so) here 的示例。这有帮助吗? 感谢那个 dtb,但我的问题是 DllNotFoundException!!!我确定文件路径是正确的!我想这一定是一个愚蠢的问题! :) 【参考方案1】:

您需要将库编译为共享库:静态库不能在运行时使用 P/Invoke 加载。 您添加了 main() 函数的事实表明您正在将代码编译为可执行文件。 所以你首先要学习如何编译一个共享库,你可以试试这样的:

gcc -shared -o libtestcpp.so testcpp.cpp

然后将DllImport名称改为完整库名的路径:

DllImport("/home/yourlogin/MonoCsTest/bin/Debug/libtestcpp.so")

您犯的另一个错误是没有考虑 C++ 强制名称修改:这里更简单的解决方案是将 Sum() 导出为使用 extern "C" 包围它的 C 函数。

要诊断此类错误,通常可以使用以下命令从单声道启用调试日志记录:

MONO_LOG_LEVEL="debug" MONO_LOG_MASK="dll" mono yourprog.exe

【讨论】:

名称修改通常会导致 EntryPointNotFound 异常,而不是 DllNotFound。据我所知,Mono 可以使用从可执行文件和共享库中导出的符号(不过我对此并不完全确定)。 我当然知道异常类型(fwiw,我实现了 mono 的这一部分),这就是为什么我首先向他指出他得到 DllNotFound 异常的原因,后来我指出了另一个一旦他解决了第一个问题,他就会遇到。至于您不确定的部分:您的句子不正确。当使用特殊的 DllImport 名称“__Internal”时,Mono 可以从(正确链接的)共享库中加载导出的符号,并从嵌入 mono 的 进程(注意,不可执行)中加载全局导出的符号。有一个半例外:PIE 可执行文件。 但是 PIE 可执行文件基本上是共享库,我不想把它们拿出来,因为人们已经很困惑了:)【参考方案2】:

只要导出一个符号并且 Mono 可以理解参数(足以将数据编组到/来自它们),那么是的,您可以这样做。我认为 PInvoke 上的 Mono 页面实际上提到您可以调用由库和可执行文件导出的函数,包括嵌入 Mono 的可执行文件。

您需要验证该符号确实被导出,更重要的是,它没有被破坏或者您在 C# 端匹配它。那是我遇到过最愚蠢问题的地方。

【讨论】:

问题是DllNotFoundException!是因为数据类型不匹配吗?我不认为! :) 从错误中,我猜它只是找不到库(或者这是最好的起点)。你检查过路径,确保名称是正确的吗? 是的,我检查了!我还检查文件权限。 :'( 尝试将 C++ 库或可执行文件与 Mono 可执行文件放在同一目录中,并将其作为工作目录运行。这个页面或许能提供更多帮助,是 Mono 的互操作信息:mono-project.com/Interop_with_Native_Libraries

以上是关于在 ubuntu 操作系统中从单声道 P/Invoke g++的主要内容,如果未能解决你的问题,请参考以下文章

在 ionic 4 中从单页视图导航到侧面菜单布局

csharp Vagrant - Ubuntu精确32,单声道3.28和南希托管示例

在 Matlab 中从声音文件中删除人声

如何将我的单声道程序添加到启动中?

如何在 Ubuntu 中从终端运行 Qtcreator?

在 VSCode 和 Ubuntu 中从 go 回到定义?