加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Ubuntu Linux---GNU libc库

发布时间:2016-01-26 20:41:49 所属栏目:Linux 来源:网络整理
导读:除了libc和libm库,UNIX系统库没有其他标准的命名规范。Linux上的一些系统库可能和UNIX平台上库的名称不同,这就需要知道Linux上各库所包含和支持的功能。表3-2

在Linux上,使用动态链接的应用程序需要和库libdl.so一起链接,也就是使用选项-ldl。但是,编译时不需要和动态装载的库一起链接。程序3-1是一个在Linux上使用dl*例程的简单示例。

(代码)(P70-73)

编译该程序:

(代码)(P73第5行)

$ make

运行程序:

(代码)(P73第15行)

$ ./main

用ldd命令检查可执行程序:

$ ldd ./main

(代码)(P73第19行)

可以看到,可执行程序main没有引用动态装载的库。

3.5.2 延迟重定位(Lazy Relocation)

延迟重定位/装载是一个允许符号只在需要时才重定位的特性。这常在各UNIX系统上解析函数调用时用到。当一个和共享库一起链接的应用程序几乎不会用到该共享库中的函数时,该特性被证明是非常有用的。这种情况下,只有库中的函数被应用程序调用时,共享库才会被装载,否则不会装载,因此会节约一些系统资源。但是如果把环境变量LD_BIND_NOW设置成一个非空值,所有的重定位操作都会在程序启动时进行。也可以在链接器命令行通过使用-z now链接器选项使延迟绑定对某个特定的共享库失效。需要注意的是,除非重新链接该共享库,否则对该共享库的这种设置会一直有效。

3.5.3 初始化(initializing)和终止化(finalizing)函数

有时候,以前的代码可能用到了两个特殊的函数:_init和_fini。_init和_fini函数用在装载和卸载某个模块(注释14)时分别控制该模块的构造器和析构器(或构造函数和析构函数)。他们的C语言原型如下:

(代码)(P74第8行)

void _init(void);

void _fini(void);

当一个库通过dlopen()动态打开或以共享库的形式打开时,如果_init在该库中存在且被输出出来,则_init函数会被调用(注释15)。如果一个库通过dlclose()动态关闭或因为没有应用程序引用其符号而被卸载时,_fini函数会在库卸载前被调用。当使用你自己的_init和_fini函数时,需要注意不要与系统启动文件一起链接。可以使用GCC选项-nostartfiles做到这一点。

但是,使用上面的函数或GCC的-nostartfiles选项并不是很好的习惯,因为这可能会产生一些意外的结果。相反,库应该使用__attribute__((constructor))和__attribute__((destructor))函数属性来输出它的构造函数和析构函数。如下所示:

(代码)(P74第21行)

void __attribute__((constructor)) x_init(void)

void __attribute__((destructor)) x_fini(void)

构造函数会在dlopen()返回前或库被装载时(注释16)调用。析构函数会在这样几种情况下被调用:dlclose()返回前,或main()返回后,或装载库过程中exit()被调用时。

3.6 系统调用

系统调用是用户程序请求内核为调用线程或进程提供具体服务的接口。因为UNIX平台上的一些系统调用是与操作系统密切相关的,因此在Linux上可能不存在类似的系统调用。这种情况下,就需要在Linux上实现一个包裹函数(wrapper)。

Linux上系统调用的列表位于/usr/include/asm/unistd.h中。本书的附录部分还对Linux和UNIX系统(如Solaris,HP-UX等)进行了并列比较。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读