一、系统说明
Ubuntu12.04TLS 64位
二、制作静态库
(1)编写需要制作成静态库的程序(根据实际情况进行编写,这里只是一个简单例子)
//bar.h #ifndef _BAR_H #define _BAR_H void bar(int i); #endif
//bar.c #include <stdio.h> #include <stdlib.h> #include "bar.h" void bar(int i) { printf("Hello! I'm bar, i=%d\n", i); }
//foo.h #ifndef _FOO_H #define _FOO_H void foo(int i); #endif
//foo.c #include <stdio.h> #include <stdlib.h> #include "foo.h" void foo(int i) { printf("Hello! I'm foo, i=%d\n", i); }
(2)制作成静态库
gcc -fPIC -c foo.c bar.c ar rcs libstaticlib.a foo.o bar.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" int main() { int i = 9; int j = 8; foo(i); bar(j); return 0; }
gcc main.c -o test -L. -lstaticlib ./test
结果:
Hello! I'm foo, i=9
Hello! I'm bar, i=8
三、用静态库制作成动态库
(1)将上一步得到的静态库解压,获得目标文件
ar -x libstaticlib.a
将获得目标文件foo.o 和 bar.o
(2)将目标文件制作成动态库
gcc -fPIC -shared -o libsharedlib.so foo.o bar.o
生成动态库 libsharedlib.so
(3)将动态库路径键入到加载路径下
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
这样做只是暂时的,终端关闭就失效了,想永久生效,修改配置文件
(3)简单测试
gcc main.c -o test -lsharedlib ./test
结果:
Hello! I'm foo, i=9
Hello! I'm bar, i=8
四、总结
(1)-fPIC 参数不仅在制作动态库的时候使用,当将静态库制作到64位机器上的动态库时,编译静态库时要使用这个参数
(2)动态库需要制动加载的路径,因此需要配置加载路径
(3)动态库与静态库的一些优缺点
内存中每一个程序都会有一个代码的拷贝,而动态库在内存中只有一份
静态库编译的程序可以直接移植到其他地方运行,而动态库的程序将因找不到链接库将不能执行
静态库编译的程序大小很大
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。