我有一个项目,在这个假设示例中称为 Super,其中包含一组 .so
文件,这些文件内置于 /home/whatever/super/
中。在运行时,规范配置文件告诉 Super 使用它们的 .so
名称加载哪些插件。这是在 Ubuntu 16.04 上。
示例插件:
/home/whatever/super/magic.so
/home/whatever/super/wow.so
/home/whatever/super/awesome.so
我已经设置了 LD_LIBRARY_PATH
:
export LD_LIBRARY_PATH=/home/whatever/super
在 Super 中,我使用 dlopen()
加载模块:
std::string filename = "magic.so"
dlopen(filename.c_str(), RTLD_LAZY)
至此,一切正常。现在我正在尝试打包我的项目,这意味着将东西移动到正确的系统目录。我现在已经切换到使用 /usr/lib/x86_64-linux-gnu/super/
作为插件的基本路径,如下所示:
/usr/lib/x86_64-linux-gnu/super/magic.so
/usr/lib/x86_64-linux-gnu/super/wow.so
/usr/lib/x86_64-linux-gnu/super/awesome.so
我还清除了 LD_LIBRARY_PATH
。我将 dlopen()
代码更新为如下所示:
std::string filename = "super/magic.so"
dlopen(filename.c_str(), RTLD_LAZY)
不幸的是,系统不会加载我的模块。我收到此错误:
Cannot load library: super/magic.so: cannot open shared object file: No such file or directory
我确认 /etc/ld.so.conf.d/x86_64-linux-gnu.conf
存在并包含:
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
我做错了什么?我已经确认 /usr/lib/x86_64-linux-gnu/super/magic.so
存在。为什么加载程序不在 /usr/lib/x86_64-linux-gnu
的子目录中搜索 .so
文件?我显然不想将 .so
文件的完整路径硬编码到我的 C++ 代码中。
最后,对于放置插件的位置和加载方法,这是一个好的方法吗?
最佳答案
恐怕 Glibc 不会处理 dlopen
中的相对文件路径(可能还有其他函数)。 Here您可以看到 任何 斜线都会导致它将文件名视为绝对文件名,而不会在标准路径中搜索它。
我认为最好的解决方案是将绝对插件路径传递给 dlopen
。也可能要求 Glibc 维护者更好地诊断此类错误。
关于c++ - 使用 dlopen() 引用共享库插件的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42564706/