同事(先进哥)对全局变量用法的一点建议:
我们当前很多库中使用了很多对象全局变量。用来执行一些初始化过程,并用以保证这些对象变量在库加载时即可使用。
但是过多的、分散在各处的全局变量,以及同库或者不同库的全局变量之间的依赖关系,
使得初始化过程的逻辑变得复杂,也因此带来过一些棘手的问题。
所以,这里整理了一下gcc编译器对库初始化和释放过程的接口,以便对全局变量及初始化过程进行统一管理
1. _init()和_fini()函数
gcc向每个so库中,默认添加_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解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...
例如,如果使用动态连接C运行时库(例如 `msvcrt.dll`),则DLL内的全局变量将在EXE内的全局变量之前初始化。这是因为DLL的初始化发生在EXE的初始化之前,确保了DLL中的全局变量已经准备好供EXE使用。 总之,理解...
在`change_greeting`函数中,我们使用`global`关键字声明`greeting`是全局变量,然后将其值更改为"Bonjour"。当我们调用这个函数后,全局变量`greeting`的值在函数外部也被改变。 需要注意的是,虽然可以修改全局...
因为直接通过ID作为全局变量访问元素可能会引发潜在的问题和混淆,特别是在大型项目或多人协作的代码库中。 当我们在控制台尝试访问一个ID为`foo`的元素时,如`foo`,虽然可以成功获取该元素,但浏览器会发出警告,...
在Vue.js框架中,设置全局变量或数据是十分常见的需求,这可以帮助我们在多个组件之间共享信息...然而,为了遵循良好的编程实践,建议在必要时才使用全局变量,并优先考虑使用状态管理工具如Vuex来处理复杂的状态共享。
在Python编程中,全局变量通常在单个文件或模块中使用,但在多文件项目中,有时需要在不同的文件之间共享同一个变量。为了实现这一需求,Python提供了多种方法。本篇文章将详细探讨如何在Python中实现跨文件全局变量...
JQuery是JavaScript中使用最为广泛的一个库,它简化了HTML文档遍历、事件处理、动画和Ajax交互。Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个页面的情况下,能够更新部分网页的技术。在Web开发...
4. **宏定义和全局变量**:手册会列出所有预定义的宏和全局变量,这些常量和变量用于设置硬件参数或表示特定的状态。 5. **错误处理**:HAL库使用统一的错误处理机制,包括返回错误码和异常处理。手册会解释如何...
extern用于声明在其他文件中定义的全局变量。 动态存储区的特点是在运行阶段申请内存单元,程序运行时可用,用完即回收,再次使用时会重新分配新的存储单元,这一特点保障了系统的安全性,因为每次分配的存储单元号...
包含头文件:在需要使用库中函数的.c文件中使用#include指令包含头文件(如#include"xxx.h"),之后即可调用声明在该头文件中的函数。 需要注意的是,头文件中声明的全局变量不能直接在库外访问,如果需要修改这些...
- 在添加全局变量时选择添加网络,codesys将自动添加名称为“Connection1(UDP)”的表单,可用于设置网络变量属性。 - 对于**写属性的网络变量**,需要遵循以下规则: - 选择“写”属性(同一组只能具备“读”或...
这种类型的共享变量类似于全局变量,但具有更高的灵活性,因为它可以很容易地转换为网络发布的共享变量,从而实现跨网络的访问。单进程共享变量对于优化应用程序的结构和提高数据共享效率非常有用。 #### 七、网络...
它旨在用于讨论,原型规范以及为WebAssembly添加可变全局变量的提案的实现。 有关建议的摘要,请参见。 该规范的格式版本(包括此建议)可在此处找到: 。 来自上游存储库的原始自述文件如下... 规格 该存储库...
本文档中使用的术语包括但不限于: - **变量**:存储数据的容器。 - **全局变量**:在整个程序范围内都可访问的变量。 - **格式和风格**:指代码的缩进、命名规则、注释等视觉呈现方面。 - **库**:预先编写的代码...
- **作用域**:明确变量的作用域,比如局部变量、全局变量等,确保不会出现变量覆盖的情况。 - **1.3.2 布尔型** - **定义**:布尔类型用于表示真或假的值,在C语言中通常使用整数类型来实现布尔逻辑。 - **使用...
本文将深入探讨如何在MFC中实现主对话框与子对话框之间的数据传递,以及使用全局变量作为传递手段的优缺点。 首先,理解MFC中的对话框。在MFC中,对话框通常由一个对话框类(如CDialog)和一个对应的资源文件(.RC...
对于全局变量,一个常见的做法是将其定义放在.cpp文件中,例如`HWND g_hwndMain`,并在需要使用的其他文件中通过`extern`关键字进行声明,如`extern HWND g_hwndMain`。这样做可以避免重复定义导致的链接错误,同时...
**注意事项**: 如果在多个文件中使用相同的全局变量,需要确保只有一个文件对其进行初始化。 #### 十五、全局变量的定义位置 **知识点15:全局变量的定义位置** - **定义**: 可以在被多个`.c`文件包含的头文件中...
考虑到库的体积非常小,它很可能没有使用这些高级特性,而是直接通过全局变量或者立即执行函数表达式(IIFE)来封装代码,以保持简洁。 此外,这个库可能没有文档,但可以通过阅读"说明.txt"来理解如何使用。通常,...
**前端开源库-babel-plugin-globals** 在前端开发中,ES6模块已经成为现代JavaScript开发的标准,但并非所有浏览器都原生支持这些...不过,为了保持代码的可维护性和遵循最佳实践,建议尽可能减少对全局变量的依赖。