问题是我使用dlopen
来加载库(.so是由我编写的,它不是系统库),但我收到了标题中显示的错误。
dlfcn.h
-ldl
命令-L.
,但它不起作用。答案 0 :(得分:6)
如果你要dlopen的库不在标准搜索路径中,你有很多选择:
在dlopen中指定文件的完整路径
dlopen("/full/path/to/libfile.so");
通过LD_LIBRARY_PATH
添加到库的路径 LD_LIBRARY_PATH=/path/to/library/ ./executable
使用ld -rpath选项将库路径添加到应用程序。
g++ -link stuff- -Wl,-rpath=/path/to/library/
请注意选项1& 3将库路径硬编码到您的应用程序中。 -rpath可以选择指定相对路径,即
-Wl,-rpath=$ORIGIN/../lib/
将相对路径嵌入到应用程序中。
答案 1 :(得分:2)
dlopen的声明看起来像, void * dlopen(const char * filename,int flag);
如果将para'文件名'设置为共享库的名称,则应将当前路径添加到'LD_LIBRARY_PATH'中。例如,
1,dlopen(“libtest.so”,RTLD_LAZY)
2,在shell中,导出LD_LIBRARY_PATH =。:$ LD_LIBRARY_PATH
答案 2 :(得分:-1)
找出代码出错位置的最残酷有效的方法是以下命令,该命令将激活共享库的调试模式,并记录在案here:
export LD_DEBUG=libs
然后,你会惊讶于弹出如此多的信息。不用担心,这些信息告诉您刚输入的命令需要哪些共享库以及在何处找到所需的库。例如,如果键入reset
,屏幕将被重置,然后将打印有关共享库reset
命令需求的信息。
然后,执行“有问题”的可执行文件,看看出了什么问题。
PS.1:根据您接受的mythagal的解决方案:
在dlopen中指定文件的完整路径
的dlopen( “/全/路径/到/ 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
要了解这里发生了什么,请仔细阅读上面链接中的所有内容。
PS.3:您始终可以使用命令export LD_DEBUG=help
,export LD_DEBUG=libs
来确定-rpath
或LD_LIBRARY_PATH
如何解决您的问题。你会喜欢这种调试模式。
ldd ./YOURproblematicEXECUTABLE
此命令可以告诉您要打开的共享库是否已找到。此外,有很多方法可以解决您的问题,每种方式都有其局限性和应用。因此,我强烈建议您阅读我上面提供的链接,并了解如何选择解决问题的方法。阅读完之后,如果您确实感觉非常“好”,您还可以阅读此Better understanding Linux secondary dependencies solving with examples以获得更深入的理解。