本文共 2155 字,大约阅读时间需要 7 分钟。
本文接:
前面说过,库其实就是头文件和和.a
或.so
文件的集合,而.a
或.so
文件则是由众多.o
文件打包而成(不太准确)。所以只要有我的头文件和.o
文件,使用者就可以使用我的代码了
如下我有两个文件一个是mylib.h
,一个是mylib.c
,目的是写一个自己的打印函数
//mylib.h#includevoid Myprintf();//mylib.c#inlude "mylib.h"void Myprintf(){ printf("Hello World\n");}
接着要使用gcc -c
生成.o
文件
test
,将mylib.o
和,mylib.h
文件拷贝至该目录下 test.c
文件,该文件就可以通过引入mylib.h
的方式,调用Myprintf
函数实现功能。需要注意的是编译时注意加入mylib.o
文件,因为编译时依赖这个文件 .a
文件是因为.o
文件太多了,所以方便管理 现在我要实现一个静态库,我的库主要提供两个功能:加法运算和减法运算
依次创建add.c add.h sub.c sub.h
四个文件
//add.h#includeint add(int x,int y);//add.c#include "add.h”int add(int x,int y){ return x+y;}//sub.h#include int sub(int x,int y);//add.c#include "sub.h"int sub(int x,int y){ return x-y;}
接着把所有的.c
文件编译为对应的.o
文件
ar -rc
命令(rc表示replace and creat),输入ar-r c libMYLIB.a add.o sub.o
,表示将add.o
和sub.o
打包为libMYLIB.a 好的现在只需将头文件和.a
文件交付给别人就可以使用了。所以要进行最后一次封装,创建一个目录 my_method
,然后在该目录下分别创建两个目录:include
和lib
,将.h
文件拷贝至include
目录下,将.a
文件拷贝至lib
目录下
好的,现在有一个程序test.c想要使用我的库
比如要使,库中的加法,那么就编写test.c如下
#include#include "add.h"int main(){ int x=10; int y=20; printf("%d\n",add(x,y)); return 0;}
然后编译,输入:gcc -static -o test.exe test.c -I./my_method/include -L./my_method/lib -lMYLIB
其中的一些选项解释如下
I./my_method/include
:告诉编译器去哪里寻找头文件L./my_method/lib
:告诉编译器库在哪里-lMYLIB
:告诉编译器要使用哪个库(需要注意libMYLIB.a
真正的库名是MYLIB
)结果如下,编译成功,返回结果也是正确的
讲完静态库之后,动态库就很好理解了。首先要将对应的.c
文件编译为.o
文件,编译时要加入-fPIC
,表示产生位置无关码,打包时和静态有区别,打包动态库时还是使用gcc,同时加入-shared
选项,表示生成共享库格式
这个过程稍显麻烦,所以使用Makefile一次性编写
libMYLIB.so:add.o sub.o gcc -shared -o $@ $^add.o:add.c gcc -fPIC -c add.csub.o:sub.c gcc -fPIC -c sub.c.PHONY:cleanclean: rm -rf *.o libMYLIB.so my_method.PHONY:packagepackage: mkdir -p my_method/include mkdir -p my_method/lib cp *.h my_method/include cp *.so my_method/lib
依然按照静态库的那个步骤,编译时不要加入-static选项:gcc -o test.exe test.c -I./my_method/include -L./my_method/lib -lMYLIB
LD_LIBRARY_PATH
。所以我们要把当前库的绝对路径导入到该环境变量之中。 转载地址:http://ojsi.baihongyu.com/