【发布时间】:2013-07-28 21:23:39
【问题描述】:
我正在尝试制作一个 C++ 库,我需要在加载时调用一个函数来对其进行初始化。我使用的是GCC,所以我尝试使用__attribute__((constructor)),该函数实际上是在加载时调用的。
但上述函数使用了不同翻译单元中的静态对象,因此未指定这些翻译单元中的静态对象是否在我需要使用它们时进行初始化。所以,举个例子,如果我想在这个函数中使用 std::cout,我就完蛋了。
下面的代码 sn-p 很好地说明了这个问题:
#include <iostream>
void __attribute__((constructor)) init()
{
std::cout << "Test\n";
}
int main(int argc, char* argv[])
{
return 0;
}
这里,函数init()会在加载时被调用,但未指定此时std::cout是否被初始化,并且在尝试执行第5行时很可能会出错。
所以我的问题是,是否有可能确保我需要在加载时调用的初始化函数将在所有静态对象构建后执行?
编辑:我忘了提到这个库将通过使用 LD_PRELOAD 环境变量在另一个程序中预加载来使用,以便拦截某些调用,所以我不能要求用户在他的 main 中调用 lib_init() 函数()。
【问题讨论】:
-
除非你把它放在
dllmain或main中。 -
问题是,我正在做一个库,所以我不能使用main,我使用的是GCC,所以我也不能使用dllmain。我不想相信这会是 MSVC 特有的功能。
-
@Loki Astari:我认为这不会解决问题:不同翻译单元中的对象仍然可能未初始化。
-
如果您能提供帮助,请不要接触特定于编译器的内容。使用正确的单例对象,以保证它们的初始化以正确的顺序发生。
-
std::cout 很特别,我相信有一些保证。并且访问其他翻译单元中的对象,您应该使用函数静态成员变量来保证初始化的顺序。但这不是你的问题。您需要将更多细节放入您需要什么的问题中。