C专家编程 八 函数库链接的時特殊秘密

       当使用函数库时,需要掌握5个基本的、不明显的约定。绝大多数C语言书籍或手册对 此并没有作出清楚的解释。这可能是因为编程语言的文档认为链接是操作系统的一部分.但 是,设计操作系统的人们《认为链接是语言的一部分。结果,除非是链接器开发队伍的人参 与进来,否则人们顶多也就偶尔提到它一下。这里展示了关于UNIX链接的真实情况:
1. 动态库文件的扩展名是“.so”,而静态库文件的扩展名是“.a”
        按照约定,所有动态库的文件名的形式是libname.so (可能在名字中加入版本号)。这样, 线程函数库便被称作libthread.so。静态库的文件名形式是libname.a,共享archive的文件名 形式是libname.sa。共享archive只是一种过渡形式,帮助人们从静态库转变到动态库。共享 archive现在也已过时。
2. 例如,你通过-lthread选项,告诉编译链接到libthread.so
        传给C编译器的命令行参数里并没有提到函数库的完整路径名。它甚至没有提到在函数 库目录中该文件的完整名字!实际上,编译器被告知根据选项-Iname链接到相应的函数库, 函数库的名字是linbname.so——换句话说,“lib”部分和文件的扩展名被省掉了,但在前面 加一个 “1”

3. 编译器期望在确定的目录找到库

        这里,你可能会疑惑,编译器是怎么知道该往什么目录寻找函数库呢?就像存在一种特 殊的规则用于查找头文件一样,编译器也自有办法来寻找函数库。它查看一些特殊的位置, 如在/usr/lib中查找函数库。例如,线程库位于/usr/lib/libthread.so。
        编译器选项-Lpathname告诉链接器一些其他的目录,如果命令中加入了-1选项,链接 器就往这些目录查找函数库。系统中存在几个环境变量,LD_LIBRARY_PATH和 LD—RUN一P:ATH,也是用于提供这类信息。出于安全性、性能和创建/运行独立性方面的考虑, 使用环境变量的做法现在己经不提倡。一般还是在链接时使用-Lpathname和-Rpathname选项。

4. 观察头文件,确认所使用的函数库

        你有可能遇见的另一个关键问题是“我怎么知道必须链接到哪些函数库? ”答案正如 ObiWanKenobi在伽所清楚表达的那样(大意):“卢克,使用源码! ”。如果观察程序 中的源代码,就会发现自己调用了一些自己不曾实现的函数。例如,如果程序跟三角有关, 可能会调用像sin()和cos〇这样的函数,它们可以在math函数库中找到。文档中显示了每个 函数期望接收的正确的参數类型,并说明它位于哪个函数库。

       一个很好的建议就是可以观察程序所使用的相#include指令。在程序中所包含的每个头文 件都可能代表一个必须链接的库。这个建议也适用于C++。这里出现了-…个名字不一致的大 问题。头文件的名字通常并不与它所对应的函数库名相似。非常遗憾丨这是你“不得不知道 的” C语言的一个混乱之处。表5-1展示了一些常见的例子。


        函数库链接所存在的另一个不一致性就是函数库所包含的某个函数的原型可能与其他头 文件中所声明的函数的原型一样。例如,在头文件<string.h>、<stdio.h>和<time.h>中声明的 函数通常是在同一个库libc.so中提供。如果你不信,可以使用run工具程序列出函数库所包 含的函数。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值