Linux共享库概述( 六 )
4.1. dlopen()dlopen函数打开一个函数库然后为后面的使用做准备 。 C语言原形是:
void * dlopen(const char *filename, int flag);
如果文件名filename是以“/”开头 , 也就是使用绝对路径 , 那么dlopne就直接使用它 , 而不去查找某些环境变量或者系统设置的函数库所在的目录了 。 否则dlopen()就会按照下面的次序查找函数库文件: 1. 环境变量LD_LIBRARY指明的路径 。
2. /etc/ld.so.cache中的函数库列表 。
3. /lib目录 , 然后/usr/lib 。 不过一些很老的a.out的loader则是采用相反的次序 , 也就是先查 /usr/lib , 然后是/lib 。dlopen()函数中 , 参数flag的值必须是RTLD_LAZY或者RTLD_NOW , RTLD_LAZY的意思是resolve undefined symbols as code from the dynamic library is executed , 而RTLD_NOW的含义是resolve all undefined symbols before dlopen() returns and fail if this cannot be done' 。如果有好几个函数库 , 它们之间有一些依赖关系的话 , 例如X依赖Y , 那么你就要先加载那些被依赖的函数 。 例如先加载Y , 然后加载X 。
dlopen()函数的返回值是一个句柄 , 然后后面的函数就通过使用这个句柄来做进一步的操作 。 如果打开失败dlopen()就返回一个NULL 。 如果一个函数库被多次打开 , 它会返回同样的句柄 。如果一个函数库里面有一个输出的函数名字为_init,那么_init就会在dlopen()这个函数返回前被执行 。 我们可以利用这个函数在我的函数库里面做一些初始化的工作 。 我们后面会继续讨论这个问题的 。4.2. dlerror()
通过调用dlerror()函数 , 我们可以获得最后一次调用dlopen() , dlsym() , 或者dlclose()的错误信息 。4.3. dlsym()
如果你加载了一个DL函数库而不去使用当然是不可能的了 , 使用一个DL函数库的最主要的一个函数就是dlsym() , 这个函数在一个已经打开的函数库里面查找给定的符号 。 这个函数如下定义:
void * dlsym(void *handle, char *symbol);
函数中的参数handle就是由dlopen打开后返回的句柄 , symbol是一个以NIL结尾的字符串 。 如果dlsym()函数没有找到需要查找的symbol , 则返回NULL 。 如果你知道某个symbol的值不可能是NULL或者0 , 那么就很好 , 你就可以根据这个返回结果判断查找的symbol是否存在了;不过 , 如果某个symbol的值就是NULL , 那么这个判断就有问题了 。 标准的判断方法是先调用dlerror() , 清除以前可能存在的错误 , 然后调用dlsym()来访问一个symbol , 然后再调用dlerror()来判断是否出现了错误 。 一个典型的过程如下:
[cpp] view plain copy print?
- dlerror(); /*clear error code */
- s = (actual_type)dlsym(handle, symbol_being_searched_for);
- if((error = dlerror()) != NULL){
- /* handle error, the symbol wasn't found */
- } else {
- /* symbol found, its value is in s */
- }
dlopen()函数的反过程就是dlclose()函数 , dlclose()函数用力关闭一个DL函数库 。 Dl函数库维持一个资源利用的计数器 , 当调用dlclose的时候 , 就把这个计数器的计数减一 , 如果计数器为0 , 则真正的释放掉 。 真正释放的时候 , 如果函数库里面有_fini()这个函数 , 则自动调用_fini()这个函数 , 做一些必要的处理 。 Dlclose()返回0表示成功 , 其他非0值表示错误 。
4.5. DL Library Example
下面是一个例子 。 例子中调入math函数库 , 然后打印2.0的余弦函数值 。 例子中每次都检查是否出错 。 应该是个不错的范例:
[cpp] view plain copy print?
- int main(int argc, char *argv){
- Linux Kernel 5.10.5发布:禁用FBCON加速滚动特性
- 35人共用一座坟!日本推出的“共享坟墓”火了
- 微软盘点12月OneDrive更新:网页端可创建共享库等
- Linux 5.11开始围绕PCI Express 6.0进行早期准备
- Fedora正在寻求协助 希望加快Linux 5.10 LTS内核测试进度
- Linux Mint 20.1 Ulyssa稳定版已确定延期至2021年初发布
- 英特尔Xe GPU在Linux 5.11上的性能表现不错
- MIPS架构厂商日渐式微 Linux报告其漏洞遭遇困难
- 哈啰出行:APP注册用户数达4亿,共享单车业务覆盖超460城
- 社区|社区团购是恶是善?会成为下一个共享单车吗?互联网巨头“掐架”所为何图?