在MacOS中无法加载动态库(DYLIB)

7

我正在尝试动态加载一个库(例如ArithmeticOprn.dylib)并调用该库中提供的方法。请参考下面的示例代码片段:

[DllImport("libdl.dylib")]
public static extern IntPtr dlopen(String fileName, int flags);

[DllImport("ArithmeticOprn.dylib")]
public static extern double Add(double a, double b);

static void Main(string[] args)
{
    dlopen("path/to/ArithmeticOprn.dylib", 2);
    double result = Add(1, 2);
}

在MacOS中运行上面的示例时,我遇到了以下异常:

无法加载DLL“ArithmeticOprn.dylib”:找不到指定模块或其某个依赖项。

但是,当我在DllImport中提供完整路径时,方法调用起作用,我可以获得预期的结果。供您参考,请参阅下面的代码片段。
[DllImport("path/to/ArithmeticOprn.dylib")]
public static extern double Add(double a, double b);

请问我漏掉了什么?提前感谢:)


1
找到类似的问题 https://stackoverflow.com/questions/12036457/unable-to-load-dynamic-library-image-mac-os-x https://stackoverflow.com/questions/21577127/unable-to-load-mac-os-x-dynamic-library-dylib-in-windows-exception-in-thread - Kumar
1
@Kumar 没有找到答案。 - Ramkumar
2
@Kumar - 是的,他说得对,没有找到答案。 - Suresh Ram
1
这是什么编程语言?C#? - Siguza
1
你应该在你的库上运行 otool -L 命令(这是 OSX 上类似于 ldd 的命令),检查哪些依赖项没有找到以及为什么没有找到。可能是它们存在,但是针对不同的架构。 - CristiFati
显示剩余2条评论
3个回答

0
我最近遇到了这个问题。我通过将.dylib文件添加到目标>构建阶段>嵌入框架中解决了它(在模拟器上运行正常,但我无法使其在iOS设备上工作)。

imported lib5.dylib

然后像这样导入它 -

[DllImport("lib5.dylib", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern int test(string s);

0

你正在尝试通过显式的 dlopen 来捷径 DllImport 的行为 - 即使用 dlopen 来指定 DllImport 应该使用的路径。问题在于,在 dlopen 被调用之前,DllImport 的链接是在 C# 运行时内部完成的。

dlopen 永远不会被考虑。

为了在没有路径的情况下使用 DllImport,您需要依赖于默认的搜索行为,即由环境变量 $LD_LIBRARY_PATH$DYLD_LIBRARY_PATH、当前工作目录、$DYLD_FALLBACK_LIBRARY_PATH 指定的位置。

例如:

env DYLD_LIBRARY_PATH=path/to/ mono test.exe

该方法使用预加载路径为path/to的mono解释器,使其能够在该位置找到dylib

其他解决方案包括将库移动到可执行文件所在的目录中,在当前工作目录中创建库的符号链接。


0

有点晚了,但最近我遇到了类似的问题,也许这会为寻找答案的其他人节省一些时间。

要记住评论中@CristiFati建议的内容很好——该库通常可能针对不同的体系结构,但正如你所说,当给定完整路径时它可以加载,因此我认为架构是正确的。

了解您是使用还是原始来运行应用程序将是有趣的,因为它们链接库的方式不同。

对于,我在这里回答了-你应该使用

  <ItemGroup>
    <BundleResource Include="<path-to>ArithmeticOprn.dylib" />
  </ItemGroup>

在您的*.csproj文件中 - 它将在编译过程中添加此本地库到创建的mono包中。

对于mono,您需要执行以下操作之一:

  1. 按照上面@Petesh建议的做法

  2. 在运行应用程序之前创建符号链接,例如:

    ln -sf ArithmeticOprn.dylib <path-to>ArithmeticOprn.dylib

  3. app.config添加到您的项目中,它会执行与2)类似的操作,例如:

    <?xml version="1.0" encoding="utf-8"?>
     <configuration>
      <dllmap os="osx" dll="ArithmeticOprn.dylib" target="path/to/ArithmeticOprn.dylib"/>
    </configuration>

希望这能帮助像我一样遇到麻烦的人,祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接