【发布时间】:2013-04-24 16:35:48
【问题描述】:
我有一个使用dlopen 加载的C 共享对象。 C 共享对象包含另一个库作为静态存档(完全指定的路径/usr/local/.../libsomelib.a)。 libsomelib.a 是一个 C++ 库,它具有全局和静态局部变量。
在 Ubuntu 上,使用 RTLD_GLOBAL 和 RTLD_GLOBAL | RTLD_LAZY 打开共享库时,静态初始化程序似乎不会运行。我看到的症状是程序崩溃。
我看到的行为似乎类似于链接-nostartfiles 或-nostdlib(但我没有使用它们)。我在 C++ Static Constructors and dlopen'd Shared Libraries 找到了一个类似的帖子,但它是针对 NetBSD 系统的。
如果 EXE 显式包含libsomelib.a 并从中调用函数,C++ 库将初始化并且程序在通过函数指针调用时不再崩溃。
编辑:这是共享对象的构建方式(这是我经历过的最简单的情况,没有混合/匹配 C 和 C++)。 cryptopp-so-test.exe 致电dlopen:
CXXFLAGS = -g -ggdb -fPIC -DDEBUG -O1 -Wall -Wextra -Wno-unused -DUSE_PRECOMPILED_HEADERS=1 -I. -I/usr/local/include/cryptopp
...
precompile:
$(CXX) $(CXXFLAGS) pch.h -o pch.h.gch
cryptopp-so-test.exe: precompile $(EXEOBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $(EXESOURCES) -ldl -lpthread
dsotest: precompile $(DLLOBJECTS)
$(CXX) $(CXXFLAGS) $(DLLSOURCES) -o dsotest-1.so -shared /usr/local/lib/libcryptopp.a
虽然上面的代码构建了一个 EXE (cryptopp-so-test.exe) 和一个 SO (dsotest-1.so),但我实际上构建并加载了 4 个共享对象(它们的构建方式相同)。
当带有 C++ 组件的 C 共享对象是 dlopen'd 时,我应该使用哪些标志(或其他方法)来确保运行静态初始化程序?
【问题讨论】:
-
这应该可以在您在
dlopen时间不做任何特别的事情的情况下工作,所以那时您没有什么特别的事情可以做。请说明您是如何创建共享对象(完整的、未经编辑的链接命令行)。如果这完全可以修复,那么它可以在那里修复。 -
谢谢扎克。 “这应该可以在你没有做任何特别的事情的情况下工作......”这就是我的想法。作为记录,我多年来一直遇到这个问题,但我现在必须解决它。
-
问:你能把它归结为一个简短的、独立的例子吗?
标签: c++ shared-libraries dlopen