C++ dlopen()正在返回0
在我的目录中,我有两个文件。一个是C++ dlopen()正在返回0,c++,linux,g++,dlopen,C++,Linux,G++,Dlopen,在我的目录中,我有两个文件。一个是foo.cpp,另一个是bar.so。在foo.cpp中,我试图加载库条。因此: #include <dlfcn.h> #include <iostream> int main() { void* handle = dlopen("bar.so", RTLD_NOW | RTLD_GLOBAL); std::cout << handle << std::endl; return 0; }
foo.cpp
,另一个是bar.so
。在foo.cpp
中,我试图加载库条。因此
:
#include <dlfcn.h>
#include <iostream>
int main()
{
void* handle = dlopen("bar.so", RTLD_NOW | RTLD_GLOBAL);
std::cout << handle << std::endl;
return 0;
}
但是,当执行test
时,会打印出0
,并根据dlopen
的文档:
如果dlopen()由于任何原因失败,它将返回NULL
那么,当库文件与CPP文件位于同一目录中时,为什么返回NULL
更新: 我现在已将
dlopen()
添加到我的CPP文件中,这将输出:
bar.so:无法打开共享对象文件:没有此类文件或目录
但我不明白bar.so
和foo.cpp
在同一个目录中,可执行文件构建在同一个目录中,运行可执行文件时我也在同一个目录中
因此,我尝试使用条的绝对路径。因此
,但随后收到一个新错误:
无效的ELF标头
在快速的谷歌搜索之后,我想这可能是因为我安装了Ubuntu。我实际上在使用MacBook,并安装了Ubuntu的本机副本(不是虚拟机)。这似乎是造成问题的原因,但我不知道如何解决它。也许这个库文件在MacBookUbuntu上不起作用
那么,当库文件与CPP文件位于同一目录中时,为什么返回NULL
.cpp
文件的位置与此处无关
可执行文件的位置(分别是的设置)是用于在运行时解析的
无论如何,LD\u LIBRRY\u PATH
不是推荐的长期解决方案。简单的方法是使用“/bar.so”
而不是“bar.so”
,这样dlopen()
首先会在当前目录中查找。但当前目录可能与存储可执行文件的目录不同。在这种情况下,dlopen()
仍将失败
另一个解决方案是在编译可执行文件(foo.cpp
在本例中)时,将-Wl,-rpath='$ORIGIN'
添加到编译标志中,并像以前一样传递“bar.so”
。当使用$ORIGIN
作为rpath时,当前目录是什么并不重要。dlopen()将始终首先查找可执行文件的目录。但请注意,这将导致首先在当前目录中查找所有库,而不仅仅是那些尝试dlopen()的库。这可能不是你想要的
因此,最好的解决方案是在运行时获取可执行文件所在目录的路径,并将其用作
bar.So
的路径。这是特定于系统的。在Linux上,请参阅:无法告诉您它失败的原因,可能有很多原因。您应该只打印dlerror()
,然后看看它是怎么说的。它应该给你一个好的方向。您可以使用dlerror()的输出编辑文章。在可执行文件上使用objdump
,查看是否有RPATH
条目列出包含库的目录。您需要”/bar.so“
。否则,dlopen()。这样,当前目录是什么并不重要dlopen()
将始终首先查找可执行文件的目录。但请注意,这将导致首先在当前目录中查找所有库,而不仅仅是那些您尝试dlopen()
的库。这可能不是你想要的。绝对最好的解决方案是获取可执行文件和运行时的目录,并使用它。
g++ foo.cpp -ldl -o test