一、系统说明

Ubuntu12.04TLS 64位


二、制作静态库

(1)编写需要制作成静态库的程序(根据实际情况进行编写,这里只是一个简单例子)

//bar.h#ifndef_BAR_H#define_BAR_Hvoidbar(inti);#endif

//bar.c#include<stdio.h>#include<stdlib.h>#include"bar.h"voidbar(inti){printf("Hello!I'mbar,i=%d\n",i);}

//foo.h#ifndef_FOO_H#define_FOO_Hvoidfoo(inti);#endif

//foo.c#include<stdio.h>#include<stdlib.h>#include"foo.h"voidfoo(inti){printf("Hello!I'mfoo,i=%d\n",i);}

(2)制作成静态库

gcc-fPIC-cfoo.cbar.carrcslibstaticlib.afoo.obar.o

编译生成foo.o 和 bar.o, 最终生成libstaticlib.a

其中最重要的一个是 -fPIC 参数,如果没有这个参数,如果是32位系统在制作动态库的时候没有问题,但是64位的系统就有问题,制作动态库的时候将

报错:

/usr/bin/ld: foo.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
foo.o: could not read symbols: Bad value
collect2: ld 返回 1
因此将静态库制作成64位机器上的动态库,必须使用-fPIC参数


(3)简单测试

//main.c#include<stdio.h>#include<stdlib.h>#include"foo.h"#include"bar.h"intmain(){inti=9;intj=8;foo(i);bar(j);return0;}

gccmain.c-otest-L.-lstaticlib./test

结果:

Hello! I'm foo, i=9
Hello! I'm bar, i=8

三、用静态库制作成动态库

(1)将上一步得到的静态库解压,获得目标文件

ar-xlibstaticlib.a

将获得目标文件foo.o 和 bar.o

(2)将目标文件制作成动态库

gcc-fPIC-shared-olibsharedlib.sofoo.obar.o

生成动态库 libsharedlib.so

(3)将动态库路径键入到加载路径下

exportLD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

这样做只是暂时的,终端关闭就失效了,想永久生效,修改配置文件

(3)简单测试

gccmain.c-otest-lsharedlib./test

结果:

Hello! I'm foo, i=9
Hello! I'm bar, i=8


四、总结

(1)-fPIC 参数不仅在制作动态库的时候使用,当将静态库制作到64位机器上的动态库时,编译静态库时要使用这个参数

(2)动态库需要制动加载的路径,因此需要配置加载路径

(3)动态库与静态库的一些优缺点

内存中每一个程序都会有一个代码的拷贝,而动态库在内存中只有一份

静态库编译的程序可以直接移植到其他地方运行,而动态库的程序将因找不到链接库将不能执行

静态库编译的程序大小很大