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

时间:2018-11-23 11:54:13

标签: c# macos dllimport dylib dlopen

我正在尝试动态加载库(例如 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);

能否让我知道我想念的是什么?在此先感谢:)

2 个答案:

答案 0 :(得分:0)

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

dlopen永远不会进来。

要使用dlopen 而没有路径,您需要依赖默认的搜索行为,即环境变量DllImport,{{ 1}},当前工作目录$LD_LIBRARY_PATH

例如,

$DYLD_LIBRARY_PATH

运行带有$DYLD_FALLBACK_LIBRARY_PATH预先加载的路径的单声道解释器,从而使其可以在该位置找到env DYLD_LIBRARY_PATH=path/to/ mono test.exe

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

答案 1 :(得分:0)

有点晚了,但是我最近遇到了类似的问题,也许这样可以节省其他人寻找答案的时间。

请牢记@CristiFati在评论中的建议-总体上来说,lib可能针对不同的arch,但是正如您所说的,如果给定完整路径,它将加载,因此我认为该拱门是正确的。

当您使用 Xamarin.Mac 或原始的 mono 来运行您的应用程序时,这会很有趣,因为它们链接库的方式不同。

对于 Xamarin.Mac ,我回答了here-您应该使用

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

在* .csproj中-它将将此本机lib添加到在编译过程中创建的mono bundle中。

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>

希望可以帮助像我这样的泡菜的人,祝你好运!