【问题标题】:How to link a .so file to a managed DLL with mono如何使用单声道将 .so 文件链接到托管 DLL
【发布时间】:2023-03-18 02:37:01
【问题描述】:

我正在.net 中的 ARM 处理器上为嵌入式 linux 编写程序,该程序使用单声道执行。我发现我可以在我的 PC 上简单地编译为 x86 或 x64 架构,将 Debug 目录复制到 linux,然后使用 mono myProgram.exe 运行程序。该程序可以像这样完美地运行,mono 似乎可以解决架构不匹配的问题。直到今天,当我尝试合并外部原生 DLL 时,情况都是如此。

我有外部 DLL 的 x86 和 x64 位体系结构,并且都可以在桌面环境中正常工作。我有一个 shim 类,它使用 [DllImport] 加载外部函数。但是,当我在带有 Mono 的嵌入式 linux 上尝试这个时,我得到了一个 BadImageFormat 异常。我的猜测是,Mono 在启动时会以某种方式在 exe 中转换已编译的 DLL,但对外部却没有。

其他一些信息: 1. 我没有本地外部库的源代码。我有 x86、x64 和一个 .so 库。 2. 我尝试制作一个可访问 .so 的管理 C++ shim,但由于 windows 无法识别 .so 文件,因此无法在桌面上编译它。

一些想法: 1. 有没有办法将原生 DLL 嵌入托管,这样 Mono 也会转换原生 DLL? 2. 我可以将 .so 文件链接到托管 C++ 项目吗? 3. 有没有办法告诉 Mono 在执行期间合并那个 Dll?

最终,我正在寻找一种包含在 exe 中的解决方案,它允许我像以前一样简单地运行它并控制本机系统。

【问题讨论】:

  • 很抱歉,但我真的不认为这会奏效。您有一个为 x86/x64 Windows 编译的非托管 C++ DLL,并且您正尝试在 ARM Linux 上运行它。这种完全不匹配是BadImageFormatException 最可能的原因。
  • 你能定义什么是“C# Native DLL”吗?您是在谈论非托管/本机 DLL 还是用 C# 编写的 .NET 程序集? .NET DLL 是托管的(非本地的)并在运行时通过 JIT 编译器运行,这就是为什么它们(大部分)与架构无关。原生 DLL 没有那么奢侈。
  • @Ciaran_McCarthy 总的来说,我同意你的看法,但奇怪的是,我将 x86 和 x64 编译的 DLL 复制到了 Arm,使用 Mono 运行得很好。
  • @RonBeyer 这是一个错字。抱歉,它是一个托管 C++ DLL。
  • 您通过DllImport 导入的DLL 是托管的还是非托管的(您提到.so 文件,所以我猜是非托管的)?并非 .NET 的所有内容都与平台无关,尤其是当您加载可能依赖于特定平台 API(如 win32 或 winmm)的外部本机库时。

标签: c# mono native dllimport managed-c++


【解决方案1】:

如果您拥有适用于 Windows 和 Linux 的所有 .dll 和 .so 文件,您可能可以使用 Mono 的 dll 映射功能。 (https://www.mono-project.com/docs/advanced/pinvoke/dllmap/) 用于将 Windows dll 名称映射到 Linux so 名称。

.Net 无法识别这一点,但 Mono 可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多