前言

静态链接库会编译进可执行文件,并被加载到内存,会造成空间浪费

静态链接库对程序的更新、部署、发布带来麻烦。如果静态库更新了,使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)

动态库在程序编译时并不会被链接到目标代码中,而是在执行文件中记录对动态库的引用,在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署和发布带来的麻烦,用户只需要更新动态库即可,增量更新。

Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。

特点

  • 动态库把对一些库函数的链接载入推迟到程序运行的时期
  • 可以实现进程之间的资源共享。(因此动态库也称为共享库)
  • 将一些程序升级变得简单。
  • 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

生成动态链接库

  1. 编写源文件
  2. 将一个或几个源文件编译链接,生成共享库。
  3. 通过 -L<path> -lxxx 的gcc选项链接生成的libxxx.so。
  4. 把 libxxx.so 放入链接库的标准路径,或指定 LD_LIBRARY_PATH,才能运行链接了libxxx.so的程序。

例子

源文件

add.c

int add(int a, int b)
{
return a + b;
}

subtract.c

int subtract(int a, int b)
{
return a - b;
}

编译

gcc -fPIC -c add.c
gcc -fPIC -c subtract.c

其中,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性

链接

gcc -shared -o libmymath.so subtract.o add.o

-shared是链接选项,告诉gcc生成动态库而不是可执行文件

这两步可以合并成一个命令:

gcc -o libmymath.so -fPIC -shared subtract.c add.c

编写头文件

#ifndef _MYMATH_H_
#define _MYMATH_H_ int add(int, int);
int subtract(int, int); #endif

使用链接库

main.c

#include <stdio.h>
#include "mymath.h" int main()
{
printf("%d, %d\n", add(, ), subtract(, )); return ;
}

链接

gcc main.c -L. -lmymath

如果同一目录下同时存在同名的动态库和静态库,比如 libmymath.so 和 libmymath.a 都在当前路径下,则gcc会优先链接动态库。

运行

当执行 ./a.out,发现程序报错

./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

这涉及到程序如何定位共享库文件

  1. 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)
  2. 对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段 -- 环境变量LD_LIBRARY_PATH -- /etc/ld.so.cache文件列表 -- /lib/,/usr/lib 目录找到库文件后将其载入内存。

/etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的

所以,我们想让程序找到自己写的动态链接库,有如下方法:

  • 指定 LD_LIBRARY_PATH 环境变量为 libmymath.so 文件所在的目录
  • 编辑/etc/ld.so.conf文件,加入库文件所在目录的路径; 同时,运行ldconfig ,该命令会重建/etc/ld.so.cache文件
  • 把 libmymath.so 拷贝到/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作

我们可以执行:

LD_LIBRARY_PATH=. ./a.out

Makefile

.PHONY: all

all: build target

build: libmymath.so
libmymath.so: add.o subtract.o
gcc -o $@ -shared $^
add.o: add.c
gcc -c -fPIC $<
subtract.o: subtract.c
gcc -c -fPIC $< target: a.out
a.out: main.c
gcc main.c -L. -lmymath .PHONY: clean
clean:
rm *.o a.out libmymath.so

linux动态链接库的更多相关文章

  1. Linux动态链接库的创建与使用

    Linux动态链接库的创建与使用1. 介绍     使用GNU的工具我们如何在Linux下创建自己的程序函数库?一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数 ...

  2. linux 动态链接库查找方法;查找动态链接库位置; LIBRARY_PATH 和 LD_LIBRARY_PATH 的区别;LD_LIBRARY_PATH and LD_RUN_PATH的区别;

    今天配置之前项目的时候,发现有些动态链接库变了,想看看现在应用在使用哪些动态链接库的时候,进一步查了点资料: 下面针对linux动态链接库查找方法和动态链接库位置配置的过程进行记录: LIBRARY_ ...

  3. Linux 动态链接库

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  4. Linux 动态链接库学习笔记

    参考资料: http://www.linuxidc.com/Linux/2012-01/50739.htm http://www.yolinux.com/TUTORIALS/LibraryArchiv ...

  5. linux动态链接库---一篇讲尽

    一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.s ...

  6. Linux动态链接库的生成和使用

    目录 1. 编写C程序 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是ca ...

  7. Linux 动态链接库 - dll劫持

    如何使用动态链接库 Linux下打开使用动态链接库需要三步(实际上和windows下基本一样):1.加载动态链接库,通过调用库函数dlopen()获得链接库的句柄,对应于windows下的 AfxLo ...

  8. Linux 动态链接库(.so)的使用

    1. 背景 库:就是已经编写好的,后续可以直接使用的代码. c++静态库:会合入到最终生成的程序,使得结果文件比较大.优点是不再有任何依赖. c++动态库:动态库,一个文件可以多个代码同时使用内存中只 ...

  9. Linux动态链接库的使用

    1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库.通过动态链接库可以实现多个 ...

随机推荐

  1. RESTful架构及SOA架构简单解析

    1.RESTful架构 本人也是刚接触ASP.NET开发,以下为自己简单的理解,并做了一些记录,表述不当或者错误之处还请指正,在此谢过. 首先,REST(REpresentational State  ...

  2. VS配置Qt

    https://blog.csdn.net/qq_35488967/article/details/71516640

  3. Oracle数据库设计实例-实时生产效率系统数据库设计

    Oracle数据库设计实例-实时生产效率系统数据库设计 引言 1.1 设计前提 某部门经理要求IT部门设计一个流水线实时生产效率系统,用来统计实时的生产量和效率.流水线有数百条,实时间隔为1min. ...

  4. Hyperledger Fabric 1.0 学习搭建 (四)--- 创建Fabric多节点集群

    4.1.配置说明 首先可以根据官方Fabric自带的e2e_cli列子中的集群方案来生成我们自己的集群,与案例不同的是我们需要把容器都分配到不同的服务器上,彼此之间通过网络来进行通信,网络构建完成后则 ...

  5. OC基础数据类型-NSNumber

    1.NSNumber:专门用来装基础类型的对象,把整型.单精度.双精度.字符型等基础类型存储为对象 //基本数据类型 //专门用来装基础类型的对象 NSNumber * intNumber = [[N ...

  6. SAP CRM One order里user status和system status的mapping逻辑

    Below example show: How the mapping relationship between User status and System status maintained in ...

  7. (第二场)A Run 【动态规划】

    链接:https://www.nowcoder.com/acm/contest/140/A 题目描述: White Cloud is exercising in the playground.Whit ...

  8. 根据用户id生成一个唯一邀请码

    需求描述:根据用户id生成与之对应的唯一邀请码,范围为‘0-9A-Z’. 这个需求的重点在于加粗的部分,也就是要能够根据邀请码反推出用户ID,这样邀请码就不用入库了,在用户量很大的情况下,性能可以得到 ...

  9. stixel上边缘

    上图是2^x-1的曲线,取值范围在(-1,正无穷) 上面两个公式组成了隶属函数(membership)表示隶属度,隶属度就是衡量这个点同下边缘点是否属于同一个物体.实际上M函数就是2^x-1,但M函数 ...

  10. js 飞机大战

    完整文件及代码可以在网盘下载,下载链接为:https://pan.baidu.com/s/1hs7sBUs 密码: d83x 飞机大战css定义: <style> #container{ ...