linux

位置:IT落伍者 >> linux >> 浏览文章

在Linux创建库函数(5)


发布日期:2019年09月06日
 
在Linux创建库函数(5)

摘要:和luster学习在Linux创建库函数

不兼容的函数库

如果一个新版的函数库要和老版本的二进制的库不兼容则soname需要改变对于C语言一共有个基本的理由使得它们在二进制代码上很难兼容

o 一个函数的行文改变了这样它就可能与最开始的定义不相符合

o 输出的数据项改变了

o 某些输出的函数删除了

o 某些输出函数的接口改变了

如果你能避免这些地方你就可以保持你的函数库在二进制代码上的兼容或者说你可以使得你的程序的应用二进制接口(ABIApplication Binary Interface)上兼容

动态加载的函数库Dynamically Loaded (DL) Libraries

动态加载的函数库Dynamically loaded (DL) libraries是一类函数库它可以在程序运行过程中的任何时间加载它们特别适合在函数中加载一些模块和plugin扩展模块的场合因为它可以在当程序需要某个plugin模块时才动态的加载例如Pluggable Authentication Modules(PAM)系统就是用动态加载函数库来使得管理员可以配置和重新配置身份验证信息

Linux系统下DL函数库与其他函数库在格式上没有特殊的区别我们前面提到过它们创建的时候是标准的object格式主要的区别就是这些函数库不是在程序链接的时候或者启动的时候加载而是通过一个API来打开一个函数库寻找符号表处理错误和关闭函数库通常C语言环境下需要包含这个头文件

Linux中使用的函数和Solaris中一样都是dlpoen() API当时不是所有的平台都使用同样的接口例如HPUX使用shl_load()机制而Windows平台用另外的其他的调用接口如果你的目的是使得你的代码有很强的移植性你应该使用一些wrapping函数库这样的wrapping函数库隐藏不同的平台的接口区别一种方法是使用glibc函数库中的对动态加载模块的支持它使用一些潜在的动态加载函数库界面使得它们可以夸平台使用具体可以参考tml 另外一个方法是使用libltdl是GNU libtool的一部分可以进一步参考CORBA相关资料

dlopen()

dlopen函数打开一个函数库然后为后面的使用做准备C语言原形是

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

如果文件名filename是以/开头也就是使用绝对路径那么dlopne就直接使用它而不去查找某些环境变量或者系统设置的函数库所在的目录了否则dlopen()

就会按照下面的次序查找函数库文件

环境变量LD_LIBRARY指明的路径 /etc/ldsocache中的函数库列表 /lib目录然后/usr/lib不过一些很老的aout的loader则是采用相反的次序也就是先查/usr/lib然后是/lib

Dlopen()函数中参数flag的值必须是RTLD_LAZY或者RTLD_NOWRTLD_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()这个函数返回前被执行我们可以利用这个函数在我的函数库里面做一些初始化的工作我们后面会继续讨论这个问题的

dlerror()

通过调用dlerror()函数我们可以获得最后一次调用dlopen()dlsym()或者dlclose()的错误信息

上一篇:一起学习在linux下使用汇编语言(5)

下一篇:精彩arm linux演义