Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ dlopen()正在返回0_C++_Linux_G++_Dlopen - Fatal编程技术网

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