文章目录

  • 共享库简介
  • 共享库制作
    • 代码实现
    • 创建共享库
  • 链接使用共享库
  • 小结

共享库简介

共享库的本质就是将多个目标文件打包成一个文件。链接共享库就是在可执行文件中调用共享库中函数的指令处插入一些指令,在运行时通过执行这些指令来完成加载共享库以及计算出所调函数入口地址的动作。使用共享库的可执行文件占用磁盘和内存相对于静态库要小。共享库中的代码一旦被修改,只要函数接口不变,无需重新链接。使用共享库的可执行文件在运行时,需要依赖共享库。一旦共享库被删除,则可执行文件无法运行。

共享库的文件形式为:lib<库名>.so

共享库制作

代码实现

假如我们制定一个数学操作的共享库,在同一个文件夹下,有如下文件:
– add.c
– add.h
– sub.c
– sub.h

add.c为加法操作实现,sub.c为减法操作实现。
代码如下:

add.h

#ifndef C_ADD_H
#define C_ADD_Hint add(int a, int b);#endif //C_ADD_H

add.c

#include "add.h"int add(int a, int b) {return a + b;
}

sub.h

#ifndef C_SUB_H
#define C_SUB_Hint sub(int a, int b);#endif //C_SUB_H

sub.c

#include "sub.h"int sub(int a, int b) {return a - b;
}

创建共享库

首先我们将源代码编译为目标文件:
gcc命令需要加-fPIC选项,将目标文件编译为位置无关码,动态库内部跳转都是通过全局映射表来将程序中的虚拟地址找到动态库的实际地址,来进行调用的。
gcc -fPIC -c add.c sub.c
执行完毕后会生产add.o和sub.o文件。

然后使用gcc的-shared选项来表明创建一个共享库:
gcc -shared -o libmymath.so sub.o add.o
执行完后,会创建一个libmymath.so文件。

链接使用共享库

我们为了使用上面的共享库,我们在如上相同文件夹下,创建一个main.c文件:
– add.c # 加法实现
– add.h # 加法头文件
– sub.c # 减法实现
– sub.h # 减法头文件
– libmymath.so # 共享库文件
– main.c # 入口主程序

main.c

#include <stdio.h>
#include "add.h"
#include "sub.h"int main(void) {int a = 20;int b = 10;printf("%d+%d=%d\n", a, b, add(a, b));printf("%d-%d=%d\n", a, b, sub(a, b));return 0;
}

我们使用#include预处理指令包含了sub.h和add.h头文件,来使用我们制作的mymath共享库。
如果我们直接gcc -o main main.c肯定会出错,因为编译器不知道add.h和sub.h是哪里来的,也不知道add和sub函数的定义在哪里。
所以我们需要使用-l选项,让编译器链接到我们制作的共享库:
gcc -o main -lmymath main.c
执行上面的命令发现还是会报错,是因为编译器默认查找的/usr/lib;/usr/local/lib系统文件夹中的库。而非我们的制作的共享库存放地址,除非将你制作的libmymath.a放到上面的lib文件夹中,那么执行上面的命令就不会有问题。如果不在上述文件夹中,则需要使用-L来指定附加库文件搜索路径。
此处我的libmymath.a在当前目录,所以执行:
gcc -o main -lmymath -L./ main.c

sudo cp libmymath.so /lib

把libmymath.so 拷贝到/lib路径下,以便可执行文件运行后加载库。

注意:gcc的-l选项后面跟的库名,只需要指定除去lib和.so后缀的中间的实际命名就可以了,编译器会自动按照lib<库名>.so规则来搜索库文件。
如果预处理指令#include包含的头文件不在当前目录下,则需要在gcc的时候,通过-I选项来指定头文件附加搜索路径。

此时在当前目录生成了main的可执行文件。
运行得到如下:

20+10=30
20-10=10

可执行文件在运行期需加载动态库文件,所以如果动态库被删除,那么执行文件会报错。

至此,从动态库的制作到链接使用就结束了。

小结

创建动态库gcc编译目标文件需使用-fpic选项来为目标文件生成位置无关码:
gcc -fPIC -c xx1.c xx2.c
将多个目标文件打包成一个libxx.so文件:
gcc -shared -o libxx.so xx1.o xx2.o
在可执行程序编译链接共享库,和链接静态库是一样的:
gcc -l<库名> -L<库附加搜索路径> xx.c

C语言 共享库(动态库)制作相关推荐

  1. Linux-(C/C++)生成并使用静态库/动态库

    静态库/动态库概要 在Windows下静态库的后缀为:.lib.动态库后缀为:.dll:而在Linux下静态库的后缀为:.a.动态库的后缀为:.so. 那么什么是静态库呢? 首先我们来看看程序编译的大 ...

  2. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统. ...

  3. 【Android NDK 开发】Visual Studio 2019 使用 CMake 开发 JNI 动态库 ( 动态库编译配置 | JNI 头文件导入 | JNI 方法命名规范 )

    文章目录 I . JNI 与 NDK 区别 II . Visual Studio 编译动态库 III. 配置 导入 jni.h 头文件 IV . IntelliJ IDEA Community Edi ...

  4. 软件库Library之静态库\动态库和静态加载\动态加载

    软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...

  5. 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )

    文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  6. NDK01-打包静态库 动态库在mk和cmake环境配置使用

    动态库和静态库 动态库: libxxx.so 运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的.使用场景就是 高德百度sdk对外开房 静态库: libxxx.a 编译期把静 ...

  7. C语言学习笔记--动态库和静态库的使用

    link 1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件. (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块 ...

  8. linux下的C语言开发(动态库)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 动态链接库不是linux独有的特性,在windows下面也存在这样的特性.一般来说,windo ...

  9. 易语言 标准c 动态库,易语言Dll动态库的开发

    一.关于易语言DLL 易语言Dll动态库的开发是编程当中和其他语言开发进行交互必不可少的方法之一,从易语言3.6版开始,已经能够支持对DLL动态链接库的开发, 编译出的DLL是标准的DLL,和其他编程 ...

最新文章

  1. 成为梵高、毕加索?你最喜欢的人脸识别与神经风格迁移来啦!
  2. Row size too large ( 8126)(解决)
  3. httpclient 实现文件上传中转
  4. android自动接听和挂断电话
  5. 时间操作(Java版)—将毫秒转换为年月日时分秒
  6. 97年世界黑客编程大赛冠军作品(大小仅为16KB),惊艳世界的编程巨作
  7. 转载-如果你不熟悉Material Design,请一口吃下这篇干货!
  8. lammps教程:高熵合金建模之set type/ratio命令
  9. 火山PC模块使用案例-动态创建多个组件教程
  10. 看Spring实战有感(一)
  11. 2021年西式面点师(初级)考试题及西式面点师(初级)
  12. R语言中写SQL语句
  13. 全干式光缆与普通光缆的区别
  14. 在有赞做java有发展吗_响应式架构与 RxJava 在有赞零售的实践
  15. 多迪php,多迪PHP项目经理深度解析:PHP应用性能优化指南!
  16. 某大学开田径运动会,现有12名选手参加100米比赛,对应的运动员号及成绩如表所示,请按照成绩排名并输出,要求每一行输出名次、运动员号及成绩
  17. linux-2.6.32在mini2440开发板上移植 ---W35型LCD驱动移植
  18. 复旦计算机崔万云,复旦大学2016年国家公派研究生项目拟推荐名单公示
  19. 曾经难忘的经历1--保研路
  20. 常见的限流算法的原理以及优缺点

热门文章

  1. bzoj 3277 串 后缀树+子树不同数个数
  2. LeetCode-Remove Duplicates from Sorted Array-从有序数组移除重复-简单逻辑
  3. .NET分布式事务处理
  4. PHP调用外部服务获取IP地域信息实现信息的地域性关联
  5. 【数据结构与算法】之深入解析“石子游戏”的求解思路与算法示例
  6. Python之深入解析Vulture如何一键找出项目中所有无效的代码
  7. iOS之深入解析AppDelegate重构
  8. 【数据结构与算法】之深入解析“复制带随机指针的链表”的求解思路与算法示例
  9. Metal之简单渲染动态切换屏幕颜色
  10. 336. Palindrome Pairs 回文对