Linux下C编程:关于静态链接库
在C语言的层面上,对代码的反复操作凡是是通过库(library)的方法来实现的。传统意义上的库指的是今后缀.a末了的文件。严格来讲,函数库该当分为两种:静态链接库和动态链接库,也称动态共享库。静态链接库凡是是指以.a为后缀的文件,而动态链接库则经常以.so为后缀名。
静态链接库其实就是把一个或多个方针文件(即编译生成的.o文件)归档在一个文件中。从此,当需要利用这个静态库中的某个成果时,将这个静态库与要生成的应用措施链接在一起。
来讲讲ar东西~~~~
在Linux上平台上最常用的归档东西是GNU的tar,可是要构建静态库却不能利用tar,而要利用另一个东西ar。tar和ar都是归档东西,可是它们的目标是差异的。tar仅仅是用来建设归档文件(即凡是以.tar为后缀的文件)的,ar也完成上述事情,可是做了一些特另外处理惩罚,它会为被归档的方针文件中的标记成立索引,当和应用措施链接时,成立的这些索引将接纳链接进程。
ar较量常常用到的就是有三个呼吁选项:r(插入)、c(建设)和s(成立索引),并且这三个选项往往是一起利用。参数r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。假如若干模块中有一个模块在库中不存在,ar显示一个错误动静,并不替换其他同名模块。默认的环境下,新的成员增加在库的末了处,可以利用其他任选项来改变增加的位置。参数c:建设一个库。不管库是否存在,都将建设。参数s:建设方针文件索引,这在建设较大的库时能加速时间。(增补:假如不需要建设索引,可改成大写S参数;假如。a文件缺少索引,可以利用ranlib呼吁添加)
此刻假设有两个C文件,foo.cbar.c。首先将foo.c和bar.c编译为方针文件foo.o和bar.o,然后将这两个方针文件归档为一个静态链接库。
// bar.c #include "foobar.h" char * bar(void) { printf("This is bar! library1 iscalled\n"); return ("bar"); }
//foo.c #include "foobar.h" char * foo(void) { printf("This is foo!library2 iscalled!\n"); return ("foo"); }
//foobar.h #ifndef _FOOBAR_H_ #define _FOOBAR_H_ #include <stdlib.h> #include <string.h> #include <stdio.h> extern char *foo(void); extern char *bar(void); #endif
执行命令呼吁:~~~~
#gcc -c foo.c -o foo.o #gcc -c bar.c -o bar.o #ar rcs libfoobar.a foo.o bar.o
这基于PC平台的,假如是对付嵌入式平台的构建静态链接库而言,进程也是完全一样,独一需要改变的大概是所用的东西名称。好比,假如要是为ARM-Linux构建静态库,那么大概需要利用arm-linux-ar。这里尚有一个东西是nm,它可以用来取得方针文件的标记(symbol)信息。这里,nm打印出了libfoobar.a中的两个标记:foo和bar。这两个标记暗示的都是函数,因此它们的标记值为0,标记范例为T(text,即暗示该标记位于代码段)。最后一列给出的是标记的名称。
#nm libfoobar.a foo.o: 0000000000000000 T foo U puts bar.o: 0000000000000000 T bar U puts
现的静态库是有了,要怎么利用这样的静态库呢。应用措施要利用静态库就必需要与静态库链接起来。这里假设有一个main.c的C文件。应用措施与静态库的链接是在编译期完成的.
#gcc -g -o foobar main.c -L. –lfoobar 可能直接:gcc –o foobar main.c libfoobar.a [email protected]:~/program$ ./foobar This is foo!library2 is foo()=foo This is library1 is called bar()=bar
总结一下啦~~~~
静态链接库是一种“复制式”的链接进程。何谓“复制式”的链接进程呢,当静态链接库与应用措施链接时,链接器会将静态链接库复制一份到最终获得的可执行代码中去。好比:此刻有两个应用措施A和B,两者都要用到libfoobar.a所提供的成果。那么,在编译链接A时,链接器将复制一份libfoobar.a到A最终的可执行代码中去,libfoobar.a中的调试信息也会被复制,同样,在链接B时,链接器也会复制一份libfoobar.a到B最终的可执行代码中去。这就是“复制式”链接的意义。
#p#分页标题#e#
查察foobar措施用到的动态链接库:
$ ldd foobar linux-gate.so.1 => (0xffffe000) libc.so.6 => /lib/libc.so.6 (0xb7e29000) /lib/ld-linux.so.2 (0xb7f6e000)
查察全套文章:http://www.bianceng.cn/Programming/C/201212/34807.htm