问题是我使用dlopen
加载一个库(.so是由我编写的,不是系统库),但我得到了标题中显示的错误。
- 我已经包含了
dlfcn.h
- 在编译器中,我使用了
-ldl
命令 - 我想要加载的只是源代码文件夹,我尝试添加
-L.
,但它没有起作用。
问题是我使用dlopen
加载一个库(.so是由我编写的,不是系统库),但我得到了标题中显示的错误。
dlfcn.h
-ldl
命令-L.
,但它没有起作用。找出代码错误最残酷而有效的方法是使用以下命令, 它将为共享库激活调试模式,文档在此处here:
export LD_DEBUG=libs
然后,您会惊讶地发现有这么多信息弹出来。不要担心,这些信息告诉您刚才输入的命令需要哪些共享库以及定位这些所需库的位置。例如,如果您键入 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
为了理解这里正在发生的事情,请仔细阅读上面链接中的所有内容。
PS.3:您可以随时使用命令export LD_DEBUG=help
、export LD_DEBUG=libs
来查明-rpath
或LD_LIBRARY_PATH
如何解决您的问题。您会喜欢这种调试模式。
PS.4:找出问题的一种不那么残酷的方法:
ldd ./YOURproblematicEXECUTABLE
这个命令可以告诉你要打开的共享库是否存在。此外,有很多方法可以解决你的问题,每种方法都有其局限性和应用场景。因此,我强烈建议你阅读我上面提供的链接,并了解如何选择解决问题的方法。在阅读完之后,如果你真的感觉非常“好”,你也可以阅读这篇文章《通过示例更好地理解 Linux 二级依赖项解决方案》以深入了解。
dlopen("/full/path/to/libfile.so");
LD_LIBRARY_PATH=/path/to/library/ ./executable
g++ -link stuff- -Wl,-rpath=/path/to/library/
-Wl,-rpath=$ORIGIN/../lib/
将相对路径嵌入应用程序。
void* handle = dlopen(SO_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if(handle == NULL)
{
printf(LOG_ERROR, "Error: %s\n", dlerror());
assert(0);
}
这将报告错误的详细原因
dlopen的声明如下:
void *dlopen(const char *filename, int flag);
如果你将参数'filename'设置为共享库的名称,则应该将当前路径添加到'LD_LIBRARY_PATH'中。例如:
1. dlopen("libtest.so" , RTLD_LAZY)
2. 在shell中,输入命令export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
对于我的情况,解决方案非常简单:
路径应该是绝对路径,除非明确指定为相对路径
所以我进行了替换:
dlopen("mylib.so", RTLD_NOW)
使用
dlopen("./mylib.so", RTLD_NOW)
问题已解决。