Linux下动态库和静态库制作与调用

1.动态库和静态库简介

  静态库是指在应用中,有一些公共代码需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。
  动态库又称动态链接库英文为DLL,是指DynamicLinkLibrary 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
  静态库:在编译的时候加载生成目标文件,在运行时不用加载库,在运行时对库没有依赖性。
  动态库:在目标文件运行时加载,对库有依赖性。

 1.1 Linux下动态库和静态库命令方式

  动态库命名方式:libxxx.so。其中so是shared objecd的缩写,即可以共享的目标文件,lib为库的固定格式,xxx为库名称,.so为动态库后缀。
  动态库命名方式:libxxx.a xxx静态库名称。Linux 上的静态库,其实是目标文件的归档文件。

 1.2 编译生成共享库示例

  命令:gcc -fPIC -shared -o libxxx.so xxx.c
  此过程分为编译和链接两部分,-fPIC是编译选项,PIC表示要生成位置无关的代码,这是动态库的特性,-shared是链接选项,告诉gcc生成动态库而不是可执行文件。
  上述命令等同于:
  gcc -fPIC -c xxx.c
  gcc -shared -o libxxx.so xxx.o
  如下代码为例实现动态库编译与调用:

[wbyq@wbyq shared]$ gcc -fPIC -shared -o libmyfile.so ./src/*.c -I./include

  gcc -I  指定头文路径

 1.3 动态库调用

[wbyq@wbyq shared]$ gcc main.c -Iinclude -lmyfile -L./lib

  gcc -L  指定动态库路径
  gcc -l  指定动态库名字

 1.4 程序运行

[wbyq@wbyq shared]$ ./a.out
./a.out: error while loading shared libraries: libmyfile.so: cannot open shared object file: No such file or directory

  错误原因:
  系统动态库默认搜索路径: /lib 和 /usr/lib
  解决办法1:将libmyfile.so 拷贝到/usr/lib或者/lib目录下。
  解决办法2:修改系统环境变量,动态库环境变量:LD_LIBRARY_PATH
  修改环境变量示例:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/hgfs/ubuntu/shared/lib

  注意:在命令行修改环境变量只对当前终端有效。
  解决办法2:修改系统启动文件
  Ubuntu下开机普通用户启动文件:~/.bashrc ~/.profile
  管理员用户:/.profile
  修改~/.bashrc文件:

  同步文件:source ~/.bashrc

2 linux静态库创建与调用

 2.1 linux静态库的命令规则

  静态库libxxx.a   xxx静态库名称。Linux 上的静态库,其实是目标文件的归档文件。

 2.2 linux静态库创建步骤

  (1)编写源文件,通过gcc -c生成目标文件。
  (2)用ar归档目标文件,生成静态库。
  (3)配合静态库,写一个使用静态库中函数的头文件。
  (4).使用静态库时,在源码中包含对应头文件,链接是记得链接自己的库。

 2.3 生成静态库

[wbyq@wbyq shared]$ gcc -c src/*.c -Iinclude  #生成 .o文件
[wbyq@wbyq shared]$ ar crv -o ./lib/libmyfile2.a ./*.o #生成静态库
a - ./my_cat.o
a - ./my_cp.o
a - ./my_du.o

 2.4 调用静态库和查看动态库信息

[wbyq@wbyq shared]$ ar t ./lib/libmyfile2.a  #查看静态库信息
my_cat.o
my_cp.o
my_du.o
[wbyq@wbyq shared]$ gcc main.c -L./lib -lmyfile2 -o app -Iinclude #调用静态

3.gcc编译器常用选项

 3.1 gcc基本用法

  使用 gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。 GCC 编译器的调用参数大约有100 多个,这里只介绍其中最基本、最常用的参数。
  gcc 最基本用法:gcc [参数] [文件名称]

 3.2 常用参数

  -c 只编译:不链接成为可执行文件,编译器只是由输入的.c 等源代码文件生成.o 为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
  -o output_filename:确定输出文件的名称为 output_filename,同时这个名称不能和源文件同名。如果不给出这个选项, gcc 就给出预设的可执行文件 a.out。
  -g:产生符号调试工具(GNU 的 gdb)所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选项。
  -O:对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。
  -O2:比-O 更好的优化编译、链接,当然整个编译、链接过程会更慢。
  -E:仅执行编译预处理;
  -S:将 C 代码转换为汇编代码;

 3.3 编译时指定库文件和头文件路径

 -L:指定动态库路径(可以指定多个路径)。
  示例: gcc test.c -o app -L/usr/lib -L ./lib
 -I:指定头文件存放的路径(可以指定多个路径)。
  示例: gcc test.c -I ./ -I /include
 -l:指定库名称(可以指定多个路径)。
  示例: gcc test.c -l my_test -l func

4.linux下采用dlopen调用动态库

 4.1 dlopen调用动态库意义

  为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。 linux 提供了加载和处理动态链接库的系统调用,非常方便。
  生成动态库:gcc -fPIC -shared libxxx.so -o xxx.c

 4.2 dlopen系列函数介绍

#include <dlfcn.h>
void *dlopen(const char *filename, int flags);
函数功能:打开动态库
形参:filename --动态库路径+名字 例:./lib/libmyfile.so
   flags --RTLD_LAZY使用时解析(暂缓解析)
   RTLD_NOW --立刻解析
返回值: handle --成功返回库引用信息,失败返回NULL

int dlclose(void *handle);
函数功能:关闭动态库
形参:handle --dlopen函数返回值

void *dlsym(void handle, const charsymbol);
函数功能:
符号解析
形参:handle --dlopen函数返回值
   symbol --要解析的符号
返回值:成功返回符号地址,
    失败返回NULL

char *dlerror(void); //打印错误信息

  注意:调用dlopen时需要通过-ldl指定动态库名字

 4.3函数解析示例

#include "./include/my_file.h"
#include <dlfcn.h>
#include <stdio.h>
int main()
{int (*p)(const char *);//定义一个函数指针/*打开动态库*/void *handle=dlopen("./lib/libmyfile.so",RTLD_LAZY);if(handle==NULL){printf("动态库解析失败%s\n",dlerror());//打印错误信息return 0;}/*符号解析*/p=dlsym(handle,"my_cat");int res=p("main.c");printf("res=%d\n",res);p=dlsym(handle,"my_du");p("main.c");//typedef unsigned int u32;typedef int (*my_cp)(const char *,const char *);//my_cp表示函数指针类型my_cp test;//定义函数指针变量test=dlsym(handle,"my_cp");test("main.c","test.c");dlclose(handle);//关闭动态库
}

 4.4变量解析示例

#include "./include/my_file.h"
#include <dlfcn.h>
#include <stdio.h>
int main()
{int (*p)(const char *);//定义一个函数指针/*打开动态库*/void *handle=dlopen("./lib/libmyfile.so",RTLD_LAZY);if(handle==NULL){printf("动态库解析失败%s\n",dlerror());//打印错误信息return 0;}/*符号解析*/p=dlsym(handle,"my_du");p("main.c");printf("-----------------------------------\n");/*解析变量*/int *p2;p2=dlsym(handle,"data");printf("*p2=%d\n",*p2);*p2=300;p("main.c");dlclose(handle);//关闭动态库
}

Linux下动态库和静态库制作与调用相关推荐

  1. Linux下用gcc生成静态库和动态库及练习使用OpenCV

    我们通常把一些公用函数制作成函数库,供其它程序使用.函数库分为 静态库和动态库两种.静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.动态库在程序编译时并不会被连接到目标代码中,而 ...

  2. Linux下ar指令与静态库转动态库方法

    1.Linux编译相关 1.1 编译 编译单个源文件 例如:main.c gcc main.c -o main ./main 编译多个源文件 例如:hello.h hello.c main.c gcc ...

  3. linux下编译自己的静态库时依赖其他的动态库,使用时出现“undefined reference to”

    对于我这个刚入IT行业不就得新手来说,在linux下链接库的时候总是会遇到各种各样奇葩的问题,最多的就是"undefined reference to"和"cannot ...

  4. 二十六篇,Linux库文件(动态库和静态库)的制作。

    一.嵌入式linux库文件概念. 1.什么是库文件? 在linux下,有非常多的库文件. 例如: /lib                        --> 存放系统自带的库文件       ...

  5. Linux下的动态库和静态库

    什么是库? 在 Linux 开发时,我们经常会看到一些形如 xxx.so 的名称出现,其中 so 是 Shared Object 的缩写,即可以共享的目标文件,也就是我们所称为的动态链接库,和在 Wi ...

  6. 技巧:Linux 动态库与静态库制作及使用详解

    http://www.ibm.com/developerworks/cn/linux/l-cn-linklib/ 技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用 ...

  7. gcc g++ Linux下动态库_静态库

    关于Unix静态库和动态库的分析 基本概念 库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在 ...

  8. Linux下动态库(.so)和静态库(.a)

     linux下有两种库:动态库和静态库(共享库) 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大. 动态库(共享库)的代码在可执行程序运行时才 ...

  9. Linux下动态库(.so)和静态库(.a) 的区别

    linux下有两种库:动态库和静态库(共享库) 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大. 动态库(共享库)的代码在可执行程序运行时才载入内 ...

最新文章

  1. C语言课后习题(34)
  2. 2.5.1.1、解析配置
  3. Linux命令 - unzip命令
  4. 计算机图形学 参数曲线和曲面的相关知识点
  5. Excel密码保护怎么解密码
  6. pandas计算对数收益率
  7. 图形化编程 html,c++图形界面编程
  8. 关于连接同一wifi,手机可以上网,电脑无法上网问题
  9. 《企业大数据系统构建实战:技术、架构、实施与应用》——2.2 大数据职位构建体系...
  10. echarts 重新加载数据
  11. 完全掌握Python: 在一门课程中使用 Python 编程所需的一切 | Complete Python Mastery
  12. C Primer Plus(6) 中文版 第9章 函数 9.1 复习函数
  13. 面试官:请解释一下Twitter的前10行源代码
  14. Salesforce Apex 中常用技能总结(持续更新)
  15. 查看表空间已使用和剩余空间大小
  16. Idea编译出现[ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter这个问题
  17. java中集合的基础知识_javaSE基础知识之集合类
  18. mysql 查询案例dept,emp表内数据
  19. Proteus中MSP430与SHT11的IIC通信问题
  20. UBNT路由模式设置

热门文章

  1. 论洗地机蓄电池在洗地机运行中起到的重要作用
  2. Control-模型预测控制(Model Predict Control,MPC)
  3. 【React】1077- React Fiber架构浅析
  4. [PTA C语言]判断回文字符串——函数题
  5. CentOS7搭建hadoop集群
  6. Spring Cloud和常用组件Consul+Fegin+zuul总结
  7. binance里面如何进行充值
  8. 如何使用uglify-js压缩指定文件夹下的js代码
  9. win10 连接打印机报0x00000709
  10. 语音社交应用的「搭积木」式实现方案