linux 编译库,linux下的库(so,a)编译流程

总结一下上周讲的库的编译流程。 linux下的库作用 对于编程人员就不必说了吧,linux下有两种库:动态库(共享库)和静态库

1.两者区别:

静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。

动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。

静态库和共享库的最大区别,静态情况下,把库直接加载到程序中,而共享库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在

2.静态库

2.1 基础概念与相关命令

a:库名格式lib.a,例如libmytest.a

b:ar命令创建静态库文件

d -----从指定的静态库文件中删除文件

m -----把文件移动到指定的静态库文件中

p -----把静态库文件中指定的文件输出到标准输出

q -----快速地把文件追加到静态库文件中

r -----把文件插入到静态库文件中

t -----显示静态库文件中文件的列表

x -----从静态库文件中提取文件

还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:

a -----把新的目标文件(*.o)添加到静态库文件中现有文件之后

b -----***************************************之前

v -----使用详细模式

ar 命令的命令行格式如下:

ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files... 参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件

cc 参数cc   -l把库做链接,静态库名称-L制定静态库路径

2.2 静态库制作及编译流程:

2.2.1.首先我们编写一个test.c程序代码,内容如下:

//#include

int test(void){

printf(" xiaolin hello");

}

2.2.2.编译test.c生成test.o文件

cc test.c -c

执行完成之后会生成一个test.o的二进制文件

2.2.3.把.o文件打成.a静态库文件

ar crs libmytest.a test.o

ar操作可以跟多个.o文件,需要空格,一起打成 mytest,使用ar -t libmytest.a  显示库包含的.o文件

2.2.4.进行静态库编译并执行

编写一个man.c程序代码,内容如下:

int main(int argc,char **argv){

printftest();}

编译main.c加载静态库

cc main.c -lmytest -L.

-l静态库名称  -L静态库路径 .指当前目录

编译完成执行./a.out输出xiaolin hello

3.动态库(共享库so)

3.1 基础概念与相关命令

a:库名格式lib.so,例如libmyshare.so

b:设置环境变量export LD_LIBRARY_PATH=`pwd`

c:   重要的dlfcn.h头文件

LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。下面详细说明一下这些函数。

3.c.1 dlerror

原型为: const char *dlerror(void);

当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

3.c.2 dlopen

原型为: void *dlopen (const char *filename, int flag);

dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

filename: 如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该文件。

(1) 用户环境变量中的LD_LIBRARY值;

(2) 动态链接缓冲文件/etc/ld.so.cache

(3) 目录/lib,/usr/lib

flag表示在什么时候解决未定义的符号(调用)。取值有两个:

1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。

2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。

dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。

3.c.3 dlsym : 取函数执行地址

原型为: void *dlsym(void *handle, char *symbol);

dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。

如程序代码: void (*add)(int x,int y); /* 说明一下要调用的动态函数add */

add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址 */

add(89,369); /* 带两个参数89和369调用add函数 */

3.c.4 dlclose : 关闭动态链接库

3.2静态库制作及编译流程:

3.2.1首先生成 具有地址无关代码(PIC).o文件,使用上个例子的test.c文件演示gcc -fPIC test.c -c  会生成test.o文件

3.2.2生成so共享库

gcc -shared test.o -o libmytest.so

检查共享库是否生成是否正确ldd libmytest.so

3.2.3编写main.c文件并编译

#include

#include

#include

int (*xiaolin)(void);

int main(int agrc,char *argv){

//打开共享库

void *handle = dlopen("libmytest.so",RTLD_LAZY);

//                                    RTLD_NOW

if(handle == (void *)0){

fputs(dlerror(),stderr);

exit(-1);

}

xiaolin= dlsym(handle,"test");

//取test函数地址赋给xiaolin函数,此时xiaolin函数具有test函数功能

printf("%d",xiaolin());

return 0;

}

dlclose(handle );//关闭共享库

3.2.4 生成可执行文件cc main.c -ldl

3.2.5执行./a.out   可能提示 No such file ,因为环境变量问题,先查看环境变量执行env 如果没有LD_LIBRARY_PATH执行echo $LD_LIBRARY_PATH 如果存在的话 再执行./a.out   应该输出 xiaolin hello

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值