C共享对象,带有c++归档,静态变量/变量,和开放
C Shared Object, With C++ Archive, Static Ctors/Dtors, and dlopen
我有一个C共享对象,我正在加载dlopen
。C共享对象包括另一个库作为静态归档(完全指定的路径/usr/local/.../libsomelib.a
)。libsomelib.a
是一个c++库,它有全局和静态局部变量。
在Ubuntu上,当打开RTLD_GLOBAL
和RTLD_GLOBAL | RTLD_LAZY
的共享库时,静态初始化器似乎没有运行。我看到的症状是程序崩溃。
我所看到的行为似乎与-nostartfiles
或-nostdlib
链接相似(但我不使用它们)。我在 c++静态构造函数和开放的共享库中发现了一个类似的线程,但它用于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时运行?
在Ubuntu上,当打开带有RTLD_GLOBAL和RTLD_GLOBAL | RTLD_LAZY的共享库时,静态初始化器似乎不会运行。
当您dlopen
共享库时,将调用全局构造函数。你很可能会得出错误的结论。
我看到的症状是程序崩溃。
该症状可能是由任何引起的。您需要在调试器中查看崩溃,并了解导致崩溃的原因,而不是盲目地猜测"静态初始化器"。
将libsomelib.a
链接到主可执行文件和将其链接到共享库之间的一个区别是,取决于哪个代码调用哪个函数,您可能最终将libsomelib.a
的不同部分包含到每个部分中(链接器只会拉入libsomelib.a
中它认为必要的部分)。
您可以尝试将整个 libsomelib.a
链接到共享库,如下所示:
g++ $(OBJS) -o dsotest-1.so -shared
-Wl,--whole-archive -lsomelib -Wl,--no-whole-archive
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 复制文件流C++静态变量
- 如何在复杂继承中访问静态成员变量
- 为什么静态数组成员变量在调用对象的实例后不显示任何内容?
- 跨模板化函数编译的静态变量
- constexpr函数中的静态constexpr变量
- 静态成员变量不会由 gettext 转换
- 从 exe 和 dll 访问静态库中的 extern 变量
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 用于定义公共变量静态常量整数的C++标准