`

库中全局变量使用的建议

 
阅读更多
同事(先进哥)对全局变量用法的一点建议:
我们当前很多库中使用了很多对象全局变量。用来执行一些初始化过程,并用以保证这些对象变量在库加载时即可使用。
但是过多的、分散在各处的全局变量,以及同库或者不同库的全局变量之间的依赖关系,
使得初始化过程的逻辑变得复杂,也因此带来过一些棘手的问题。
 
所以,这里整理了一下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参数指定的初始化构造函数。
分享到:
评论

相关推荐

    Python全局变量-全局变量命名的建议

    Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...

    python自学教程-19-修改全局变量.ev4.rar

    在`change_greeting`函数中,我们使用`global`关键字声明`greeting`是全局变量,然后将其值更改为"Bonjour"。当我们调用这个函数后,全局变量`greeting`的值在函数外部也被改变。 需要注意的是,虽然可以修改全局...

    js DOM 元素ID就是全局变量.docx

    因为直接通过ID作为全局变量访问元素可能会引发潜在的问题和混淆,特别是在大型项目或多人协作的代码库中。 当我们在控制台尝试访问一个ID为`foo`的元素时,如`foo`,虽然可以成功获取该元素,但浏览器会发出警告,...

    HAL库手册非常全面

    4. **宏定义和全局变量**:手册会列出所有预定义的宏和全局变量,这些常量和变量用于设置硬件参数或表示特定的状态。 5. **错误处理**:HAL库使用统一的错误处理机制,包括返回错误码和异常处理。手册会解释如何...

    mutable-global:可变全局变量的进出口

    它旨在用于讨论,原型规范以及为WebAssembly添加可变全局变量的提案的实现。 有关建议的摘要,请参见。 该规范的格式版本(包括此建议)可在此处找到: 。 来自上游存储库的原始自述文件如下... 规格 该存储库...

    C++, .NET 一站式示例代码库编程规范

    本文档中使用的术语包括但不限于: - **变量**:存储数据的容器。 - **全局变量**:在整个程序范围内都可访问的变量。 - **格式和风格**:指代码的缩进、命名规则、注释等视觉呈现方面。 - **库**:预先编写的代码...

    MFCdialog.rar_MFCDialog_子对话框_对话框 传递

    本文将深入探讨如何在MFC中实现主对话框与子对话框之间的数据传递,以及使用全局变量作为传递手段的优缺点。 首先,理解MFC中的对话框。在MFC中,对话框通常由一个对话框类(如CDialog)和一个对应的资源文件(.RC...

    浅谈VC++工程的文件组织 .docx

    对于全局变量,一个常见的做法是将其定义放在.cpp文件中,例如`HWND g_hwndMain`,并在需要使用的其他文件中通过`extern`关键字进行声明,如`extern HWND g_hwndMain`。这样做可以避免重复定义导致的链接错误,同时...

    JavaScript_一个超级小的Javascript自动完成自动建议库零依赖800字节的mingzip.zip

    考虑到库的体积非常小,它很可能没有使用这些高级特性,而是直接通过全局变量或者立即执行函数表达式(IIFE)来封装代码,以保持简洁。 此外,这个库可能没有文档,但可以通过阅读"说明.txt"来理解如何使用。通常,...

    前端开源库-babel-plugin-globals

    **前端开源库-babel-plugin-globals** 在前端开发中,ES6模块已经成为现代JavaScript开发的标准,但并非所有浏览器都原生支持这些...不过,为了保持代码的可维护性和遵循最佳实践,建议尽可能减少对全局变量的依赖。

    create_page_usejs

    描述中提到的“很多需要改变的字符串可以定义成一个全局变量”,这是在建议开发者使用全局变量来存储可变的内容,如配置信息或文本资源。全局变量在整个应用程序范围内都可访问,使得在不同函数或模块中修改这些值变...

    ecshop程序js库冲突patch

    1. **命名空间隔离**:将库的全局变量放入特定的命名空间中,如jQuery使用`jQuery`而不是`$`,可以通过`$.noConflict()`来释放`$`。其他库也可以采取类似措施。 2. **使用`window.onload`或`document....

    linux环境下GCC完全参考

    在学习和使用GCC的过程中,了解并熟练掌握其命令行选项、编译过程、调试方法以及与库的交互方式至关重要。提供的资源《[www.topsage.com]GCC-The.Complete.Reference.pdf》应包含了这些方面的详细信息,建议新手仔细...

    Python库 | tush-1.0.0.zip

    下面将详细讨论Python库的基本概念,以及在开发过程中使用库的重要性。 Python库是预编写好的代码集合,它们提供了丰富的功能,可以帮助开发者快速构建应用程序,减少重复劳动。这些库通常包含了类、函数和其他编程...

    Lecture_8_JavaScript最佳实践1

    Douglas Crockford提到,减少全局变量的使用可以降低与其他应用、小部件或库发生冲突的可能性。 三、始终声明局部变量 在函数内部,所有变量都应声明为局部变量,使用`var`关键字。在严格模式下,未声明的变量会被...

    tomcat配置环境变量

    通过配置环境变量,你可以确保Tomcat能够正确识别并使用JDK,加载必要的库,并且能够在命令行中方便地控制Tomcat服务的启停。此外,这也是一个学习操作系统和编程环境配置的良好实践,有助于提升问题排查和系统管理...

    C语言软件工程师笔试题大全.pdf

    全局变量可以在多个.C文件的头文件中定义,但建议使用`static`关键字限制其作用域,以避免命名冲突。`for( ; 1 ; )`和`while(1)`均表示无限循环。`do...while`和`while...do`的区别在于`do...while`至少执行一次循环...

    linux_C函数库中文手册.zip

    5. 错误处理:errno全局变量记录错误代码,perror函数用于打印错误信息。 四、Linux特定函数 1. 文件操作:open、read、write、close函数实现对文件的低级别操作。 2. 进程控制:fork、exec、waitpid用于创建、执行...

    20170628_c语言一二三四五研讨会_李智宇1

    在引用外部文件中的全局变量时,遵循就近原则,即优先使用最近的定义。 3. **内存对齐**: 内存对齐是一种优化策略,确保数据结构在内存中的布局更高效。它通常基于数据类型大小进行对齐,使得访问速度更快。例如...

Global site tag (gtag.js) - Google Analytics