Perl捕获嵌入脚本的stdout,如果在dlopen中加载共享库,则失败
Perl capture stdout of embedded script, fails if in dlopen-loaded shared lib
我在C++程序中嵌入了一些Perl代码(Ubuntu14,Perl5.18,如果这很重要的话(,我像本例中那样执行Perl。
更具体地说,I:
- 创建perl实例,然后按照"perlbed"手册中的描述加载持久性代码
-
评估一些"准备"代码:
static const char * redirPre = "$scriptOutput = "";n" "open(SCRIPTOUTPUT, '> :scalar', \$scriptOutput) || print STDERR "Failed to open scriptoutput: $!";n" "print SCRIPTOUTPUT "huhu\n";n" "select SCRIPTOUTPUT;n" "print SCRIPTOUTPUT "huhu2\n";n" "print STDOUT "huhu2a\n";n"; printf("PRE: '%s'n", redirPre); eval_pv(redirPre, FALSE);
-
评估我的实际Perl片段
现在奇怪的是,如果我静态地链接调用所有Perl函数的代码,或者如果这些函数在直接链接到主程序的共享库中,这会很好地工作,而如果这些函数位于共享库中(主程序使用dlopen加载(,这就不起作用。
Perl代码段执行正常,只是获取stdout失败。准确地说,这部分不起作用:
open(SCRIPTOUTPUT, '> :scalar', $scriptOutput) ||
print STDERR "Failed to open scriptoutput: $!";
不管我指定的是CCD_ 1还是仅指定CCD_。
有趣的是,输出也没有出现在stdout上,而是显示Failed to open scriptoutput:
(但没有任何实际错误(。
想法?
编辑:使用完全相同的代码将stdout重新路由到/tmp/xx效果很好,唯一的区别是:
"open(SCRIPTOUTPUT, '>', "/tmp/xx") || print STDERR "Failed: $!";n"
我花了很长时间仔细研究这个问题,最终发现了问题:
最初,我用dlopen("mylib.so", RTLD_LAZY)
加载了自己的共享库,该库又是用对libperl.so
的引用构建的。dlopen手册页指出,当隐式加载依赖库时,标志会向下传播,因此加载libperl也只有RTLD_LAZY。
如上所述重新路由stdout涉及Perl库scalar.so
,Perl在我的Perl代码段执行时加载它。库scalar.so
包含对PL_no_modify
的未解析引用,该引用再次在libperl.so
中定义。现在,由于我在有效调用>:scalar
1时没有指定RTLD_GLOBAL
,scalar.so
没有看到PL_no_modify
,无法加载。
在我的代码中设置了RTLD_GLOBAL
之后,它就工作了。
剩下的唯一问题是Perl为什么没有告诉我…:-|
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 使用 dlopen 加载派生的多态类
- 使用 dlopen 在 Mac 上加载 libjvm.dylib 时发出信号 SIGSEGV
- 在加载了dlopen的库中使用std::thread会导致sigsev
- 使用dlopen动态加载共享库
- 为什么主可执行文件和 dlopen 加载的共享库共享命名空间静态变量的一个副本?
- java.lang.UnsatisfiedLinkError: dlopen failed: 无法加载"libPrivateSsl.so"所需的库"libcrypto.so.1.0.0";
- C++:使用dlopen()加载共享库时未定义的符号
- 将共享库与dlopen一起使用-共享对象找不到加载程序导出的符号
- 如何找到已经通过dlopen API加载的dylib的路径
- 是动态加载库中的静态c++对象,在dlopen()返回之前初始化
- Perl捕获嵌入脚本的stdout,如果在dlopen中加载共享库,则失败
- dlopen是否重新加载已加载的依赖项?如果是,会产生什么影响
- 如何使用dlopen检查共享库是否已成功加载