首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dlopen()返回0

dlopen()返回0
EN

Stack Overflow用户
提问于 2019-06-10 20:14:44
回答 1查看 1.7K关注 0票数 2

在我的目录里,我有两个文件。一个是foo.cpp,另一个是bar.so。在foo.cpp中,我试图加载库bar.so

代码语言:javascript
复制
#include <dlfcn.h>
#include <iostream>

int main()
{
    void* handle = dlopen("bar.so", RTLD_NOW | RTLD_GLOBAL);
    std::cout << handle << std::endl;
    return 0;
}

然后,在同一个目录中,我将命令行中的代码编译为:

代码语言:javascript
复制
g++ foo.cpp -ldl -o test

但是,在执行test时,它将输出0,并根据dlopen的文档

如果dlopen()因任何原因失败,则返回NULL

那么,当库文件与CPP文件位于同一个目录时,为什么返回NULL呢?

更新:

我现在已经将dlopen()添加到我的CPP文件中,这将输出如下:

bar.so: cannot open shared object file: No such file or directory

但我不明白..。bar.sofoo.cpp位于同一个目录中,可执行文件构建在同一个目录中,在运行可执行文件时我也在同一个目录中。

因此,我尝试为bar.so使用绝对路径,但随后收到了一个新错误:

invalid ELF header

经过一个快速的谷歌,我认为这可能是由于我的Ubuntu安装。我实际上是在使用MacBook,并且已经安装了Ubuntu的本机副本(不是虚拟机)。这似乎是造成问题的原因,但我不知道如何解决。也许这个库文件不会在MacBook Ubuntu上工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-10 20:22:06

那么,当库文件与CPP文件位于同一个目录时,为什么返回NULL呢?

.cpp文件的位置在这里与此无关。

可执行文件的位置(分别是LD_LIBRRY_PATH的设置)是运行时用来解析的。

无论如何,LD_LIBRRY_PATH不是一个推荐的长期解决方案.简单的方法是使用"./bar.so"而不是"bar.so",以便dlopen()首先在当前目录中查找。但是,当前目录可能与可执行文件存储的目录不一样。在这种情况下,dlopen()仍然会失败。

另一种解决方案是在编译可执行文件时将-Wl,-rpath='$ORIGIN'添加到编译标志中(在本例中为foo.cpp),并像前面那样传递"bar.so"。当使用$ORIGIN作为rpath时,不管当前目录是什么。dlopen()总是首先查找可执行文件的目录。但是请注意,这将导致首先在当前目录中查找所有库,而不仅仅是那些尝试dlopen()的库。可能是你想要的,也可能不是你想要的。

因此,最好的解决方案是在运行时获取可执行文件所在的目录的路径,并将其用作bar.so的路径。这是针对系统的。在Linux上,请参见:Get path of executable

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56532981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档