知识大全 Linux 动态函式库解析(二)
Posted 知
篇首语:知识的价值不在于占有,而在于使用。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Linux 动态函式库解析(二)相关的知识,希望对你有一定的参考价值。
Linux 动态函式库解析(二) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
动态连结 VS 静态联结 在 Linux 中 执行档我们可以编程成静态联结以及动态连结 以下我们举一个简短的程序作为例子: #include int main() printf( test ); 若我们执行 : [root@hlchou /root]# gcc test c o test 所产生出来的执行档 test 预设为使用动态函式库 所以我们可以用以下的指令 : [root@hlchou /root]# ldd test libc so => /lib/libc so ( x ) /lib/ld linux so => /lib/ld linux so ( x ) 来得知目前该执行档共用了哪些动态函式库 以我们所举的 test 执行档来说 共用了两个动态函式库 分别为 libc so 与 ld linux so 我们还可以透过下面的 file 指令 来得知该执行档的相关属性 如下 [root@hlchou /root]# file test test: ELF bit LSB executable Intel version dynamically linked (use s shared libs) not stripped not stripped 表示这个执行档还没有透过 strip 指令来把执行时用不到的符号 以及相关除错的资讯删除 举个例子来说 目前这个test 执行档大小约为 bytes [root@hlchou /root]# ls l test rwxr xr x root root Oct : test 经过strip后 则变为 bytes [root@hlchou /root]# strip test [root@hlchou /root]# ls l test rwxr xr x root root Oct : test 不过读者必须注意到一点 经过 strip 过的执行档 就无法透过其它的除错软件从里面取得函式在编程时所附的相关资讯 这些资讯对我们在除错软件时 可以提供不少的帮助 各位在应用上请自行注意 相对于编程出来使用动态函式库的执行档 test 我们也可以做出静态联结的执行档 test [root@hlchou /root]# gcc static test c o test 透过指令 ldd 我们可以确定执行档 test 并没有使用到动态函式库 [root@hlchou /root]# ldd test not a dynamic executable 再透过指令 file 可以注意到 test 目前为 statically linked 且亦尚未经过 strip [root@hlchou /root]# file test test: ELF bit LSB executable Intel version statically linked not stripped 相信大伙都会好奇 使用静态联结 且又没有经过 strip 删去不必要的符号的执行档的大小会是多少 透过 ls l来看 我们发现大小变成 bytes 比起静态联结的执行档大了相当多 [root@hlchou /root]# ls l test rwxr xr x root root Oct : test 若再经过 strip 则档案大小变为 bytes [root@hlchou /root]# strip test [root@hlchou /root]# ls l test rwxr xr x root root Oct : test 与使用动态函式库的执行档 test 比较起来 大了约 倍 ( / ) 因此 整体来说 在使用的环境中使用动态函式库并且经过 strip 处理的话 可以让整体的空间较为精简 许多执行档都会用到同一组的函式库 像 libc 中的函式是每个执行档都会使用到的 若是使用动态函式库 则可以尽量减少同样的函式库内容重复存在系统中 进而达到节省空间的目的 笔者一年前曾写过一个可以用来删去动态函式库中不必要函式的工具 针对这个只用到了 printf 的程序来产生新的 libc so 的话 我们可以得到一个精简过的 libc so 大小约为 bytes [root@hlchoua lib]# ls l libc so* rwxr xr x root root Nov : libc so lrwxrwxrwx root root Nov : libc so > libc so 与静态联结的执行档大小 bytes 比较起来 若是在这个环境中使用了动态函式库的话成本约为 + = bytes 不过这是只有一个执行档的情况下 使用动态函式库的环境会小输给使用静态联结的环境 在一个基本的 Linux 环境中 如果大量的使用动态函式库的话 像是有 个以上的执行档的话 那用动态函式库的成本就大大的降低了 像如果两个执行档都只用到了 printf 那静态联结的成本为 * = bytes 而使用动态函式库的成本为 * + = bytes 两者相差约一倍 很明显的 我们可以看到动态函式库在 Linux 环境中所发挥的妙用 它大幅的降低了整体环境的持有成本 提高了环境空间的利用率 ld linux so 在 RedHat 中 我们可以在 /lib 或是 /usr/lib 目录底下找到许多系统上所安装的动态函式库 在文章的这个部分 笔者将把整个函式库大略的架构作一个说明 其实 Linux 跟 Windows 一样 提供了一组很基本的动态函式库 在 Windows 上面我们知道 kernel dll 提供了其它动态函式库基本的函式呼叫 而在 Linux 上面则透过 ld linux so 提供了其它动态函式库基本的函式 在笔者电脑的 RedHat 上 ld linux so 是透过 link 到 ld so(这部分需视各人所使用的 glibc 版本不同而定) rwxr xr x root root Jan : ld so lrwxrwxrwx root root Jan : ld linux so > ld so ld linux so 是属于 Glibc (GNU C Library) 套件的一部分 只要是使用 Glibc 动态函式库的环境 就可以见到 ld linux so 的踪影 接下来 我们透过指令 ldd 来验证出各个函式库间的阶层关系 首先如下图我们执行了 ldd ls ldd pwd 与 ldd vi 可以看出各个执行档呼叫了哪些动态函式库 像执行档 ls 呼叫了 /lib/libc so ( x )与 /lib/ld linux so ( x ) 而括号内的数字为该函式库载入记忆体的位置 在本文的稍后 会介绍到函式库载入时的细节 到时读者会有更深入的了解 其实我们不难发现 在 Linux 上使用动态函式库的执行档 几乎都会去呼叫 libc so 与 ld linux so 这两个动态函式库 笔者过去修改 Glibc 的套件时 也了解到在 Linux 中函式库的关系 ld linux so 算是最底层的动态函式库 它本身为静态联结 主要的工作是提供基本的函式给其他的函式库 而我们最常会呼叫的 libc so 则是以 ld linux so 为基础的一个架构完成的动态函式库 它几乎负责了所有我们常用的标准 C 函式库 像是我们在 Linux 下写的 Socket 程序 其中的connect() bind() send() 之类的函式 都是由 libc so 所提供的 也因此 libc so 的大小也是相当可观的 在 RedHat 中经过 strip 后 大小约为 bytes [root@hlchoua /root]# ldd /bin/ls libc so => /lib/libc so ( x ) /lib/ld linux so => /lib/ld linux so ( x ) [root@hlchoua /root]# ldd /bin/pwd libc so => /lib/libc so ( x ) /lib/ld linux so => /lib/ld linux so ( x ) [root@hlchoua /root]# ldd /bin/vi libtermcap so => /lib/libtermcap so ( x ) libc so => /lib/libc so ( x b ) /lib/ld linux so => /lib/ld linux so ( x ) 如下 我们透过 ldd 验证 vi 所用到的动态函式库 /lib/libtermcap so 它本身是呼叫了 libc so 的函式所组成的 [root@hlchoua /root]# ldd /lib/libtermcap so libc so => /lib/libc so ( x ) /lib/ld linux so => /lib/ld linux so ( x ) 接下来 我们依序测试了 /lib/libc so 与 /lib/ld linux so [root@hlchoua /root]# ldd /lib/libc so /lib/ld linux so => /lib/ld linux so ( x ) [root@hlchoua /root]# ldd /lib/ld linux so statically linked 我们可以整理以上的结论 画成如下的一个架构图 在这个图中 我们可以清楚的明白 ld linux so 负责了最基础的函式 而 libc so 再根据这些基本的函式架构了完整的 C 函式库 供其它的动态函式库或是应用程序来呼叫 透过笔者所写的一个 ELF 工具程序(注二) 我们也可以清楚的看到 libc so 呼叫了 ld linux so 哪些函式 [root@hlchoua /root]# /I elf /lib/libc so |more ======================================================== open_target_file:/lib/libc so ==>ld linux so __register_frame_table cfsetispeed xdr_int _t utmpname _dl_global_scope_alloc __strcasestr hdestroy_r rename __iswctype_l __sigaddset xdr_callmsg pthread_setcancelstate xdr_union __wcstoul_internal setttyent strrchr __sysv_signal ┅(more) cha138/Article/program/Oracle/201311/16795相关参考
Linux动态函式库解析(四) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 摘要我想各位读者应
LINUX系统中动态链接库的创建与使用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 大家都知道
动态库的生成 /*mysumc*/ 复制代码代码如下: #include<stdioh>#includesrch intsum(intaintb)return(a+b);&
初中数学二次函式动点问题有什么解题方法么?最好能指出资料!谢谢了第一是以静化动,把问的某某秒后的那个时间想想成一个点,然后再去解,第二是对称性,如果是二次函式的题,一定要注意对称性。第三是关系法:你可
知识大全 根据下列条件分别求二次函式的解析式(1)抛物线经过(0,3)(1,0)(3,0)
根据下列条件分别求二次函式的解析式(1)抛物线经过(0,3)(1,0)(3,0)(1)抛物线经过(0,3)(1,0)(3,0)第二个第三个点就是影象与X轴的交点了可设抛物线为y=a(x-1)(x-3)
Linux之菜鸟日记(二) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 天北京申奥成功了着实激
Linux下的编程PHP高级技巧全放送(二) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 四P
DELPHI基础教程:动态链接库编程(二)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
DELPHI基础教程:动态链接库编程(二)[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
DELPHI基础教程:动态链接库编程(二)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!