首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

库中全局变量使用的提议

2013-12-16 
库中全局变量使用的建议同事(先进哥)对全局变量用法的一点建议:我们当前很多库中使用了很多对象全局变量。

库中全局变量使用的建议
同事(先进哥)对全局变量用法的一点建议:我们当前很多库中使用了很多对象全局变量。用来执行一些初始化过程,并用以保证这些对象变量在库加载时即可使用。但是过多的、分散在各处的全局变量,以及同库或者不同库的全局变量之间的依赖关系,使得初始化过程的逻辑变得复杂,也因此带来过一些棘手的问题。?所以,这里整理了一下gcc编译器对库初始化和释放过程的接口,以便对全局变量及初始化过程进行统一管理?

?

1. _init()和_fini()函数

gcc向每个so库中,默认添加_init和_fini函数。_init在so库装载完成后执行,_fini在库卸载前执行。默认的_init和_fini符号位于C标准库中,链接时由gcc链入。?在编写so库时,可以自定义_init和_fini函数(C++中使用extern "C"),以自定义库的装载和卸载行为。但由于gcc默认会链接标准库,因此在代码中直接加入_init和_fini会报符号冲突。解决方法在于,在连接时使用参数-nostartfiles或-nostdlib,这样gcc不再链接标准库,此时库的初始化和卸载时行为,须有代码完全控制。?而在不连接标准库的情况下,如果so库中存在对象全局变量,那么so库加载时会报加载失败,因为对象全局变量的初始构造,由标准库完成。由于这个问题的存在,重写_init/_fini的做法,在当前gcc编译时不建议使用,而对于自定义初始化过程则由下面的方法实现。??2. __attribute__((constructor))和__attribute__((destructor))?gcc通过对自定义函数追加编译属性参数,指定该函数用于库加载时的初始化和卸载前的清理工作。这两个编译器属性追加在函数声明之后,如:void my_init()?__attribute__((constructor));void my_fini()?__attribute__((destructor));??一个so库中,可将多个函数声明以上的参数选项,执行时这些函数将按顺序逐个执行。由于该方法无需屏蔽gcc标准库,库中的对象全局变量可以正常创建和初始化。对象全局变量的构造函数,将优先于此attribute参数指定的初始化构造函数。

热点排行