c++ - 使用 dlopen() 引用共享库插件的正确方法是什么?

标签 c++ plugins shared-libraries ubuntu-16.04 dlopen

我有一个项目,在这个假设示例中称为 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/

相关文章:

linux - .so补丁RedHat和Ubuntu之间的版本差异

c++ - 带多个参数的显式构造函数

c++ - 使用 std::get、std::tuple_size、std::tuple_element 对元组的组件求和

javascript - 表不会显示使用 jquery sheetrock

html - Coda - 插件?跟踪分区

java - 将 ImageJ 宏命令实现到现有插件中

c++ - gcc9 和 lcov 的覆盖范围

c++ - 带有选项的 C++ 命令行参数中的 getopt

c++ - 防止 CMake 查找已安装的库而不是 "local"库

c++ - 链接器是否对静态符号或动态符号有任何偏好?