dlopen失败:无法打开共享对象文件:没有这样的文件或目录

use*_*282 6 linux

问题是我dlopen用来加载一个库(.so是由我编写的,它不是一个系统库),但我得到了标题中显示的错误.

  1. 我已经包括在内 dlfcn.h
  2. 在编译器中,我使用了-ldl命令
  3. 我想加载的只是源代码文件夹,我试图添加-L.,但它没有用.

myt*_*gel 8

如果您想要dlopen的库不在标准搜索路径中,您有许多选项:

  1. 在dlopen中指定文件的完整路径

    dlopen("/full/path/to/libfile.so");

  2. 通过LD_LIBRARY_PATH添加到库的路径

    LD_LIBRARY_PATH=/path/to/library/ ./executable

  3. 使用ld -rpath选项将库路径添加到应用程序.

    g++ -link stuff- -Wl,-rpath=/path/to/library/

请注意,选项1和3将库路径硬编码到您的应用程序中.-rpath确实有一个指定相对路径的选项,即

-Wl,-rpath=$ORIGIN/../lib/
Run Code Online (Sandbox Code Playgroud)

将嵌入相对路径的应用程序.


Han*_*IAO 6

找出代码哪里出错的最粗暴和有效的方法是以下命令,它将激活共享库的调试模式,并记录在此处

export LD_DEBUG=libs
Run Code Online (Sandbox Code Playgroud)

然后,您会惊讶于弹出了这么多信息。别担心,这些信息会告诉您刚刚键入的命令需要哪些共享库,以及在哪里可以找到这些需要的库。例如,如果您键入reset,屏幕将被重置,然后reset将打印有关共享库命令需求的信息。

然后,执行您的“有问题”的可执行文件,看看出了什么问题。


PS.1:根据您接受的 mythagal 的解决方案:

在 dlopen 中指定文件的完整路径

dlopen("/full/path/to/libfile.so");

看起来即使你在dlopen函数中使用了绝对或相对路径,目录未找到错误仍然会出现。我用的是 CentOS,我的 Debian 也有这个问题。所以我认为 mythagal 提供的第一个解决方案是错误的。您可以在我上面提到的“调试”模式中进行验证。


PS.2:如果你“安装”或“编译”一个共享库而不是通过包管理器安装它,你必须运行sudo ldconfig /path/where/not/found/shared/library/reside以通知系统新添加的共享库。例如 :

cp /etc/ld.so.cache ~/ld.so.cache.backup    
#cp -r /etc/ld.so.conf.d ~/ld.so.conf.d.backup #sometimes this backup is unnecessary.
#cp /etc/ld.so.conf ~/ld.so.conf.backup #sometimes this backup is unnecessary.
sudo ldconfig /PATH/WHERE/NOT/FOUND/SHARED/LIBRARY/RESIDE
###I am omitting the cp commands to roll back.
###For example, sudo cp -f ld.so.cache /etc/ld.so.cache
Run Code Online (Sandbox Code Playgroud)

要了解这里发生了什么,请仔细阅读上面链接中的所有内容。


PS.3 :您始终可以使用命令export LD_DEBUG=help,export LD_DEBUG=libs来找出-rpathLD_LIBRARY_PATH解决您的问题。您会喜欢这种调试模式。


PS.4:找出问题所在的不那么残酷的方法:

ldd ./YOURproblematicEXECUTABLE
Run Code Online (Sandbox Code Playgroud)

该命令可以告诉您要打开的共享库是否位于。此外,有很多方法可以解决您的问题,每种方法都有其局限性和适用性。所以我强烈建议您阅读我上面提供给您的链接,并了解如何选择解决问题的方式。看完之后,如果你真的觉得自己很“OK”,你也可以阅读这篇更好地理解Linux二级依赖解决的例子,以加深理解。