linux库使用

1、库存在的意义

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
库是别人写好的(你也可以写提供出来),现有的,成熟的,可以复用的代码,你可以拿来使用。

Linux下的dlopen、dlsym、dlclose 相当于windows平台的LoadLibrary、GetProcAddress 、FreeLibrary,可以在运行时动态加载动态库,使用其中的导出函数。但是局限在于,这样仅仅能够导出全局函数,而不能导出类的方法。所以一般动态库导出C++类实现的功能时都会设计一大堆的全局函数来包装一下。

2、静态库和共享库区别
静态库和共享库(动态库),二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

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

3、静态库
Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表
Step 2.ar命令将很多.o转换成.a,成为静态库

静态链接库 libcool.a 遵从 GNU/Linux 规定的静态链接库命名规范,必须是”libyour_library_name.a”

4、动态库

生产动态链接库
编译参数 gcc -fPIC -shared
使用so文件的编译参数
编译选项如下:gcc -rdynamic -o main main.c -ldl

选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中
(目的是能够通过使用 dlopen 来实现向后跟踪)比如日志系统,主程序里使用一套日志系统,dlopen方式打开的libso里无法使用。编译时加上这个参数,不需要增加任何代码就可以使代码通用。
使用-ldl选项指明生成的对象模块需要使用共享库

动态库的后缀是.so,它由gcc加特定参数编译产生。
在 GNU/Linux 中动态链接文件,必需通过链接器 ld 生成。假设我们有 hot.c other.c 等文件要生成动态链接库 libhot.so 。

Step 1. 首先使用如下指令得到相应的 object 文件 hot.o 和 other.o

    gcc -fPIC -c hot.c
    gcc -fPIC -c other.c

参数 -fPIC 指定生成的 object 文件为位置无关代码(position-independence code),只有 PIC 可以被用作生成动态链接库。
Step 2. 然后使用如下指令得到动态库:

 ld -Bshared -o libhot.so hot.o other.o

或者可以使用编译器的ld wrapper:

 gcc -shared -o libhot.so hot.o other.o

也可以使用编译器直接生成动态库:

 gcc -fPIC -shared -o libhot.so hot.c other.c

这里选项 -shared 指示目标文件的类型是动态链接库,动态库的命名规范是”libyour_library_name.so”

5、加载动态库
在加载动态链接库的时候,有可能会遇到加载不到的错误,.so文件明明就在当前目录下,为什么会提示找不到呢?
原来linux和windows的机制是不同的,它不会在当前目录下寻找动态连接库文件,它只会在标准路径下寻找。(The system searches only /lib and /usr/lib, by default.)。
由于系统默认加载的动态链接库路径里没有找到你的动态库,有三种解决方法:
1.在执行gcc main.c -L. -ltest -o main 前,执行

export LD_LIBRARY_PATH=$(pwd)

当前目录加入到系统动态库查询目录还可以这么写

LD_LIBRARY_PATH=./ 
export LD_LIBRARY_PATH

2.将其添加到/etc/ld.so.cache文件中。将你so所在的目录写到/etc/ld.so.conf文件里,或写个文件放到/etc/ld.so.conf.d/目录下。然后执行ldconfig该命令会重建/etc/ld.so.cache文件。
3.将你的so放在/etc/ld.so.conf里的路径位置里。

6、显示调用
包含头文件:   

#include <dlfcn.h> 
dlfcn.h : Linux动态库的显式调用

函数

void * dlopen( const char * pathname, int mode ); 

  函数描述:
  在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。
  mode:分为这两种
  RTLD_LAZY 暂缓决定,等有需要时再解出符号
  RTLD_NOW 立即决定,返回前解除所有未决定的符号。

void*dlsym(void* handle,const char* symbol)

函数描述:
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
dlclose
dlerror
dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,dlerror返回出现的错误,dlsym通过句柄和连接符名称获取函数名或者变量名,dlclose来卸载打开的库。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值