提交 8f1224e6 编写于 作者: 编程进阶之路's avatar 编程进阶之路

共享库完成

上级 5cb8c3fa
...@@ -70,4 +70,4 @@ ...@@ -70,4 +70,4 @@
:page 736}, :page 736},
:content {:text "[:span]", :image 1694437268292}, :content {:text "[:span]", :image 1694437268292},
:properties {:color "purple"}}], :properties {:color "purple"}}],
:extra {:page 757}} :extra {:page 85}}
void __attribute__ ((constructor)) some_name_load(void){
/* Initialization code */
}
void __attribute__ ((deprecated)) some_name_unload(void) {
/* Finalization code */
}
\ No newline at end of file
...@@ -182,6 +182,7 @@ ...@@ -182,6 +182,7 @@
- ((65000492-81ff-4609-bbeb-8ea00c75b906)) - ((65000492-81ff-4609-bbeb-8ea00c75b906))
- 当动态加载一个共享库时,`dlopen()` 接收的 `RTLD_GLOBAL` 标记可以用来指定这个库中定义的符号应该用于后续加载的库中的绑定操作,`--export–dynamic`链接器选项可以用来使主程序的全局符号对动态加载的库可用 - 当动态加载一个共享库时,`dlopen()` 接收的 `RTLD_GLOBAL` 标记可以用来指定这个库中定义的符号应该用于后续加载的库中的绑定操作,`--export–dynamic`链接器选项可以用来使主程序的全局符号对动态加载的库可用
- # 链接器版本脚本 - # 链接器版本脚本
collapsed:: true
- [[$green]]==**版本脚本** 是一个包含 **链接器** ld 执行的 **指令的文本文件**==。要使用版本脚本必须要指定`--version–script` 链接器选项 - [[$green]]==**版本脚本** 是一个包含 **链接器** ld 执行的 **指令的文本文件**==。要使用版本脚本必须要指定`--version–script` 链接器选项
- ```shell - ```shell
gcc -Wl,--version-script,myscriptfile.map ... gcc -Wl,--version-script,myscriptfile.map ...
...@@ -331,13 +332,32 @@ ...@@ -331,13 +332,32 @@
0000000000000000 F *UND* 0000000000000000 xyz@VER_2 0000000000000000 F *UND* 0000000000000000 xyz@VER_2
``` ```
- ## 初始化和终止函数 - # 初始化和终止函数
- [[#green]]==可以定义一个或多个在 **共享库被加载和卸载时自动执行** 的函数,这样在使用共享库时就能够完成一些初始化和终止工作了==。不管库是自动被加载还是使用 `dlopen` 接口显式加载的,初始化函数和终止函数都会被执行 collapsed:: true
- 初始化和终止函数是使用 `gcc``constructor``destructor` 特性来定义的 - [[#green]]==可以定义一个或多个在 **共享库被加载和卸载时自动执行** 的函数,这样在使用共享库时就能够完成一些初始化和终止工作了==。不管库是自动被加载还是使用 `dlopen` 接口显式加载的,初始化函数和终止函数都会被执行
- 在库被加载时需要执行的所有函数都应该定义成下面的形式 - 初始化和终止函数是使用 `gcc``constructor``destructor` 特性来定义的
- ```c - 在库被加载时需要执行的所有函数都应该定义成下面的形式
``` - ```c
void __attribute__ ((constructor)) some_name_load(void){
/* Initialization code */
}
```
- 类似地,卸载函数的形式如下
- ```c
void __attribute__ ((deprecated)) some_name_unload(void) {
/* Finalization code */
}
```
- ### `_init()``_fini()`函数
- 用来完成共享库的初始化和终止工作的一项较早的技术是在库中创建两个函数 `_init()``_fini()`。当库首次被进程加载时会执行 `void _init(void)` 中的代码,当库被卸载时会执行 `void _fini(void)` 函数中的代码
- 如果创建了`_init()``_fini()`函数,那么在构建共享库时必须要指定 `gcc -nostartfiles` 选项以防止链接器加入这些函数的默认实现。(如果需要的话可以使用 `–Wl,–init``–Wl,–fini` 链接器选项来指定函数的名称。)
- 有了 gcc 的 `constructor``destructor` 特性之后已经不建议使用 `_init()``_fini()` 函数了,因为 gcc 的 `constructor``destructor` 特性允许定义多个初始化和终止函数
-
- -
- - # 预加载共享库:`LD_PRELOAD`
collapsed:: true
- 出于测试的目的,有些时候可以有选择地覆盖一些正常情况下会被动态链接器找出的符号。要完成这个任务可以定义一个环境变量 `LD_PRELOAD`,其值由在加载其他共享库之前需加载的共享库名称构成,其中共享库名称之间用空格或冒号分隔
- # 监控动态链接器:`LD_DEBUG`
- 有些时候需要监控动态链接器的操作以弄清楚它在搜索哪些库,这可以通过 `LD_DEBUG` 环境变量来完成。通过将这个变量设置为一个(或多个)标准关键词可以从动态链接器中得到各种跟踪信息
- -
- -
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册