c++ - 带有 native 库的 Perl 模块 : Possible to get XSLoader to use RTLD_GLOBAL on dlopen?

标签 c++ c perl

标题给出了缩略版;总而言之,我有一个 C++ API 包装到 C 并通过 XS 暴露给 Perl。这多年来一直运行良好,但我们现在遇到了一个用例,我们怀疑它可能是由公共(public)库的重复加载引起的。

症状是我们有一个围绕 Tibrv 的内部 Perl 包装器。而且,我们对内部使用 Tibrv 的另一个 C++ API 进行了包装。当 Perl 脚本同时使用这两个 API 时,第二个会在创建 Tib 传输时挂起。单独而言,两者都在 Perl 中工作。

我怀疑,但没有任何证据支持,它在某种程度上与共享状态和 Perl 有关,默认情况下加载带有 RTLD_LOCAL 设置的库,可能是导致问题的原因(这是一个纯粹的直觉)。我没有任何证据支持这一点,但我知道 Tib 非常了解周围的环境,我认为这有可能。

我的问题: 是否可以使用 dlopen 标志,例如 RTLD_GLOBAL 与 Perl 的 XSLoader?即,可以在不重建 Perl/XS 的情况下打开 native 库时更改 dlopen 标志吗?

到目前为止,我在网上看到的一切似乎都表明您需要使用 DynaLoader,这将要求我们以适合从 DynaLoader (目前不是)。

我只有大约 10% 的把握这甚至可以解决真正的问题,但是知道我们是否可以轻松地覆盖 dlopen 标志将使我们可能节省几天的工作.

最佳答案

XSLoader 只是 DynaLoader 的前端。

听起来你可以添加

sub dl_load_flags { 0x01 }

到你的模块。这会被调用并传递给 flags 中的 dl_load_file,它会执行以下操作:

    if (flags & 0x01)
#ifdef RTLD_GLOBAL
        mode |= RTLD_GLOBAL;
#else
        Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
#endif
    DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
    handle = dlopen(filename, mode) ;

请注意,调用dl_load_file 以加载从您的.xs 编译的.so。据我所知,XSLoader/DynaLoader 不会为对象可能使用的库调用 dlopen,例如您遇到问题的库。

关于c++ - 带有 native 库的 Perl 模块 : Possible to get XSLoader to use RTLD_GLOBAL on dlopen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15891589/

相关文章:

c++ - std::shared_ptr 在空指针上调用非默认删除器

c - 从指针链表中删除节点

perl - 如何使 Perl 变量通过其整数引用来引用另一个变量

c++ - 为什么有 C++14/17 的网络库提案?

c++ - 如何在 g++ 中设置警告以警告返回指向局部变量的指针?

c++ - 如何通过类似 "LPTHREAD_START_ROUTINE lpStartAddress"的参数创建进程?

c - C 编程语言 (K&R) ex1-20 。我遇到了一些麻烦

c - 在文本文件 C 中最多读取两行时出现问题

perl - apache2-Ubuntu 中的 Bugzilla 安装问题

perl - 寻找适用于 Windows 10 的小型 Perl 实现