Dynamically Loaded(DL) Libraries

动态加载库(DL)库不是在程序的启动时而是偶尔(?)加载的库。他们对于应用插件和模块特别有用,因为他们允许直到被需要的时候才加载进来。例如,Pluggable Authentication Modules(PAM)系统利用DL库来允许管理者来配置和重配置权限。

They’re also useful for implementing interpreters that wish to occasionally compile their code into machine code and use the compiled version for efficiency purposes, all without stopping. For example, this approach can be useful in implementing a just-in-time compiler or multi-user dungeon (MUD).

在Linux系统中,从格式的角度来看,DL库并不特殊。他们作为标准的目标文件或者标准的共享库来被创建。主要的区别是DL库不会再程序的链接阶段或者启动阶段自动的加载进来。而是,有API来打开对应的库,寻找symbols,处理errors,和关闭库。C用户可以通过包括头文件

dlopen()

在C中,函数声明如下:

void* dlopen(const char *filename, int flag);

如果filename以“/”开头(例如,是一个绝对路径),则dlopen会直接试着使用它,而不会搜索该库。否则,dlopen()函数会按照下面的顺序来搜索相关的库:

  1. 在LD_LIBRARY_PATH环境变量所列出的目录
  2. 在/etc/ld.so.cache中声明的库(通过/etc/ld.so.conf生成的)
  3. /lib,然后是/usr/lib。注意这里的顺序。这个顺序与旧的 a.out loader是相反的。旧的a.out loader,当加载程序时,首先会搜索/usr/lib ,然后是 /lib目录。这不是正常的matter ,因为一个库应该只在一个或者另外的目录( 不会同时在),而且不同的库却又同样的名字是disaster。

在dlopen(),flag的之必须是RTLD_LAZY,RTLD_NOW, RTLD_GLOBAL这三者。RTLD_LAZY,意味着“在动态库已经运行后解决未定义的符号”。RTLD_NOW,意思是“在dlopen之前解决所有未定义的符号,如果不能解决则返回失败”。RTLD_GLOBAL意思是,库中定义的外部符号可以被之后加载的库使用。当你在调试时,你可能会用RTLD_NOW;使用RTLD_LAZY可能会导致不可理解的错误(未解决的引用)。

如果库相互依赖(例如X依赖于Y),则你需要加载依赖先,在此例,就是首先加载Y,之后X;

dlopen()返回值是一个handle,对于其他DL库使用不透明?。如果失败,则会返回NULL。如果同一个库被多次用dlopen多次加载,会返回同一个handle。

dlerror()

返回错误信息,返回string。

dlsym()

这个函数是用来在给定库的某个符号的值。示例代码如下:

void * dlsym(void *handle, char *symbol);
如果该symbol找不到的话,dlsym返回一个NULL值。
dlerror(); /* clear error code */
s = (actual_type) dlsym(handle, symbol_being_searched_for);
if ((err = dlerror()) != NULL) {
/* handle error, the symbol wasn’t found */
} else {
/* symbol found, its value is in s */
}

dlclose()

用来关闭DL库的函数。无论dlopen了多少次,一个dl库只会在dlclose关闭一次。如果一个库被deallocated,在旧的库中,它的函数_fini会被调用,但是 _fini已经被废弃不再使用。而库可以用 attribute((constructor)) and attribute((destructor))来输出路径。?

code example

 #include <stdlib.h>#include <stdio.h>#include <dlfcn.h>int main(int argc, char **argv) {void *handle;double (*cosine)(double);char *error;handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);if (!handle) {fputs (dlerror(), stderr);exit(1);}cosine = dlsym(handle, "cos");if ((error = dlerror()) != NULL)  {fputs(error, stderr);exit(1);}printf ("%f\n", (*cosine)(2.0));dlclose(handle);}

如果这个函数是写在“foo.c”文件中,你可以用以下命令来编译代码:

gcc -o foo foo.c -1dl

Program Library HOWTO(2)相关推荐

  1. Program Library HOWTO(1)

    看到一个有用的关于在Linux下创建和使用库的文档,随手翻译(不全). 原文链接:http://tldp.org/HOWTO/Program-Library-HOWTO/index.html 简介 一 ...

  2. Python Imaging Library: Script(脚本)

    Python Imaging Library: Script(脚本) 1. pildriver The pildriver tool gives access to most PIL function ...

  3. 【翻译】Android Support Library Features(二)

    原文地址:http://developer.android.com/tools/support-library/features.html 在Android Support Library包中,包含了 ...

  4. Yii2 HOW-TO(3):调试工具yii2-debug和Xdebug(失败)

    Yii 1.0时代使用CWebLogRoute 在早期Yii 1.0时代,借助于CWebLogRoute可以在指定Web页面中输入日志信息.因为现在广泛使用Yii 2.X,所以此方式使用说明不再详述. ...

  5. Tableau数据分析:NC Retail Order Data(英)Data Science Program Lab#1(GTI)

    Tableau数据分析:NC Retail Order Data(英) NCSU 2021 Summer Online Data Science Author:©Sylvan Ding

  6. GitHub 上受欢迎的 Android UI Library 整理(一)

    内容较多,可以用 ctrl+F 来搜索 抽屉菜单 https://github.com/mikepenz/MaterialDrawer ★7337 - 安卓抽屉效果实现方案 https://githu ...

  7. Yii2 HOW-TO(2):最佳实践(1)

    控制器编程最佳实践 在设计良好的应用中,控制器很精练,包含的操作代码简短: 如果你的控制器很复杂,通常意味着需要重构, 转移一些代码到其他类中. 可访问 请求 数据; 可根据请求数据调用 模型 的方法 ...

  8. oracle任务管理,Oracle 任务管理之 ----program(程序)---scheduler(计划)--Job(任务)

    对于Oracle的任务管理,主要理解清楚三个关键内容,就可以完全掌握任务,详细介绍如下: 1.概念分析 PROGRAM  --程序.可以执行的job实体. scheduler   --计划.或者是时间 ...

  9. Android .so 共享库(动态链接库)

    转载自:http://blog.csdn.net/bat603/article/details/1438408 烟雨楼 http://hi.baidu.com/yanyulou c2]$ ar -r ...

最新文章

  1. bcftools安装
  2. TimeSpan 时间间隔
  3. Windows 10如何启用ReFS弹性文件系统
  4. 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误
  5. Boost CRC的测试程序
  6. SpringCloud SpringBoot 推荐
  7. JAVA中数字格式异常,java - Java数字格式异常 - 堆栈内存溢出
  8. python老师好的长度_abc和老师好的长度都是3。( )
  9. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
  10. 洛谷 P1918保龄球
  11. IE 8 HTML Parsing Error:Unable to modify the parent container element before the child element is...
  12. SQL语句优化技术分析 整理他人的
  13. TabLayout的自定义
  14. 【工作日志】2013-02-01
  15. shiro+springMVC整合文档及Demo
  16. 文件名批量修改工具V1.0 绿色版
  17. Facebook批量养号分享
  18. 火焰焰心matlab,火焰的形貌-中性焰、碳化焰、氧化焰
  19. Markdowm编辑器推荐和Emoji 表情
  20. MFC CStdioFile简单用法

热门文章

  1. python是什么意思-python中class是什么意思
  2. python适合自学编程吗-风变编程:Python适合编程初学者学习吗?
  3. python程序-第一个Python程序——在屏幕上输出文本
  4. 普通人学python有什么用-学python日常工作有什么用?
  5. 车机“智能互联”深度评测:第三弹 吉利博越PRO与GKUI 19
  6. TypeScript简介
  7. element el-upload上传图片完成后隐藏上传
  8. 中学图书室管理用计算机,中学“学生电子阅览室管理制度”
  9. mysql数据库创建表时通过设置什么属性可以设置字段编号自动增加_Mysql数据库创建表样例和解释...
  10. 分类计数原理与分步计数原理_两种基础的计数原理