是动态加载库中的静态c++对象,在dlopen()返回之前初始化
Are static c++ objects in dynamically loaded libraries initialized before dlopen() returns?
下面的代码演示了预期的(而且可以说是直观的)行为。就像可执行程序中的静态对象在main()
进入之前被初始化一样,动态加载库中的静态对象应该在dlopen()
返回之前被初始化。
问题是:在运行时加载的库的这种行为是否以任何方式得到保证,或者它只是一个方便的事故或幸运的实现细节?我们是否可以依赖正在调用的库中静态对象的构造函数,或者我们是否必须求助于替代方案,例如标记为__attribute__((constructor))
的函数,以确保在dlopen()
调用范围内的一些期望行为?
// libtest.cpp
#include <iostream>
namespace
{
class Test
{
public:
Test() { std::cerr << "In Test()...n"; }
~Test() { std::cerr << "In ~Test()...n"; }
};
Test test; // when is this initialized?
}
// testso.cpp
#include <dlfcn.h>
#include <iostream>
int main( int ac, char* av[] )
{
if ( ac < 2 )
{
std::cerr << "Usage: " << av[0] << "library-namen";
return 1;
}
std::cerr << "Before dlopen()...n";
::dlerror();
void* _handle(::dlopen( av[1], RTLD_NOW ));
std::cerr << "After dlopen()...n";
if ( !_handle )
{
std::cerr << "Error: " << ::dlerror() << ", exiting...n";
return 2;
}
::dlclose( _handle );
std::cerr << "After dlclose()...n";
return 0;
}
编译并运行(注意dlopen()
返回前Test()
调用):
$ g++ -o libtest.so -shared -fPIC libtest.cpp
$ g++ -o testso -ldl testso.cpp
$ ./testso ./libtest.so
Before dlopen()...
In Test()...
After dlopen()...
In ~Test()...
After dlclose()...
$
。
首先:dlopen()
是令人难以置信的平台特定的,对于早期疾病症状和WebMD的情况,您应该始终咨询您的平台相关的man
页面。
这是正确的,即使dlopen()
函数家族似乎符合IEEE标准1003.1,2004版,尽管我不能告诉你今天的系统与这些标准的兼容性有多高(例如Windows有一个长期的劣质POSIX兼容性历史)。
OS/X/BSD上yes:
dlopen()
检查path
指定的mach-o文件。如果文件与当前进程兼容并且尚未加载到当前进程,它被加载并链接。链接后,如果它包含任何初始化函数,则在dlopen()
之前调用它们回报。
<>共舞,强调我的。
在Linux上,yes:
共享对象可以使用
__attribute__((constructor))
和__attribute__((destructor))
功能属性。构造函数在dlopen()
之前执行在dlclose()
之前执行析构函数回报。
<>共舞,强调我的。
在Solaris上,yes:
作为加载新对象的一部分,在
dlopen()
返回之前调用对象内的初始化代码。这个初始化是用户代码,因此,可能会产生dlopen()
无法捕获的错误。
<>共舞,强调我的。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- dlopen(RTLD_NOLOAD) 在 dlclose() 仍然返回 not null
- 使用 dlopen/dlsym 打开C++共享库 - dlsym 返回 NULL
- 是动态加载库中的静态c++对象,在dlopen()返回之前初始化
- 相当于 "bool DllMain()" 的 c/c++ Linux - 但我需要将 failure 返回给 dlopen()