当使用c ++静态初始化程序时,Linux共享库init&deinit

Joe*_*Joe 6 c++ linux gcc initialization shared-libraries

我想要自动调用来初始化和取消初始化我的共享库.

在我的共享库中,我需要对C++对象进行一些静态初始化,其中包括使用第三方代码(例如UnitTest ++).当执行我的init函数时,我需要保证,C++对象(所有链接的翻译单元)的所有静态初始化都已完成(反之亦然); 因此,与main()的执行在C++程序中可以预期的条件相同.

我已经看到很多关于linux共享库init/deinit的信息,例如:

但提供的解决方案不符合我的需求.在两种方法(__attribute__((constructor))甚至-Wl,-init,<function name>)中,似乎在完全完成C++对象的静态初始化之前调用init函数.

我也__attribute__ ((init_priority(…)))喜欢玩:

class InitAndDeinit {
public:
    InitAndDeinit() {
        // Do some initialization
    }
    ~InitAndDeinit() {
        // Do some cleanup
    }
} initAndDeinit __attribute__((init_priority(65535)));
Run Code Online (Sandbox Code Playgroud)

但是,这也不会将呼叫置于期望的位置; 即使有__attribute__((constructor(65535))).

我用gcc 4.6.4,4.7.3和4.8.1进行了测试(4.6.4显示了关于排序的略微不同的行为__attribute__((constructor))).

有什么建议?

我目前的解决方法是提供必须由应用程序手动调用的导出函数(lib_init()和lib_deinit()).

n. *_* m. 1

这是一种可能的解决方案。

TU 中的静态对象按照其定义顺序进行初始化。将特殊类型的静态对象的定义附加T到每个源文件的末尾。的构造函数T应该增加一个静态零初始化成员。一旦计数器达到模块中源文件的数量(由构建脚本确定),就调用您的lib_init().

lib_deinit()在计数器递减回零后调用。

每个图书馆都应该有自己的T.

您应该能够修改 makefile,这样就不必实际更改源文件。例如,而不是g++ -c foo.C使用g++ -c myspecialstaticinitcode.C -o foo.C -include foo.C或类似的东西。