错误:dlopen()库未加载 原因:找不到图像

14
我是这个领域的新手。 我的笔记本电脑是Macbook air,软件版本为:OS X 10.8.5(12F45)。 我正在运行一段代码,结果出现以下错误:

dlopen(/ Users / ramesh / offline / build_icerec / lib / icecube / phys_services.so,2):无法加载库:/ Users / ramesh / offline / build_icerec / lib / libphys-services.dylib 引用自:/ Users / ramesh / offline / build_icerec / lib / icecube / phys_services.so 原因:找不到图像

我进行了谷歌搜索并找到了各种答案。 我认为有效的方法是使用 -install_name @rpath/lib。 我的问题是如何在我的情况下使用它?

在安装Xcode 8后,我在使用Ruby的binding.pry时遇到了同样的问题。重新安装Ruby后,一切都正常工作了。这似乎比mah的复杂但正确的答案更容易。rvm requirements也对我有所帮助,因为我最近更新了我的系统。 - Joe Eifert
1个回答

33

在 OS X 下共享对象的位置有时会很棘手。当您直接调用 dlopen() 时,可以自由地指定库的绝对路径,这很好用。然而,如果您加载一个需要加载另一个库的库(似乎是您的情况),那么您就失去了通过直接路径指定库所在位置的控制权。

有一些环境变量可以在运行主程序之前设置,告诉动态加载器在哪里搜索所需的库。总的来说,这些不是一个好主意(但您可以通过在 OS X 系统上使用 man dyld 命令来了解它们)。

当创建一个 OS X 动态库时,它会被赋予一个安装名称;这个名称嵌入到二进制文件中,并且可以使用 otool 命令查看。 otool -L mach-o_binary 将列出您提供文件名的 mach-o 二进制文件的动态库引用;例如,这可以是主可执行文件或 dylib。

当一个动态库被静态链接到另一个可执行文件中(无论是主可执行文件还是另一个 dylib),连接的 dylib 的预期位置将基于写入其中的位置(在构建该库时或之后应用的更改)。在您的情况下,似乎 phys_services.so 是静态链接到 libphys-services.dylib 的。因此,首先运行 otool -L phys_services.so 查找 dylib 的 确切 期望位置。

install_name_tool 命令可用于更改库的预期位置。它可以在与 dylib 静态链接之前运行(在这种情况下,您无需再做任何事情),或者可以针对加载它的可执行文件运行以重写这些预期。该命令模式为 install_name_tool -change <old_path> <new_path>。例如,如果 otool -L phys_services.so 显示 /usr/lib/libphys-services.dylib,并且您想要按照您在问题中提出的方式移动它的预期位置,则可以使用 install_name_tool -change /usr/lib/libphys-services.dylib @rpath/lib/libphys-services.dylib phys_services.so
dyld 说明文档(man dyld)将告诉您如何使用 @rpath,以及其他宏,如 @loader_path 和 @executable_path。

1
你还可以尝试向连接器传递选项-Wl,-rpath,${RPATH},其中${RPATH}是库的路径,比如/foo/bar/lib。可以指定多个这样的选项,链接器将在所有这些位置搜索动态库。 - András Aszódi
如果一切都被绝对路径所定义,但我仍然无法加载库文件,有任何想法吗? - Royi
@Royi 阅读系统日志以寻找可能的线索。一个可能性是dylib的二进制类型与您的程序的二进制类型不匹配,您可以使用“file”命令检查。file /path/to/dylibfile /path/to/program。除此之外,我不知道在macOS上可能的原因是什么(尽管如果您恰好在iOS上,则沙盒化可能是一个可能的原因)。 - mah
MATLAB 只能处理具有 C API 的动态库(我不确定这里的正确单词)。我在我的 C++ 代码中使用 extern "C",在 Windows 上工作正常。由于某种原因,在 macOS 上,MATLAB 要么出现上述错误,要么无法找到该函数。 - Royi

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