当前位置:网站首页 > 编程语言 > 正文

动态库和静态库的区别在哪里(静态库和动态库的概念)



点击上方“机械电子工程技术”关注我们




在Linux系统编程中,动态库(Dynamic Library)也称为共享库(Shared Library),是一种在程序运行时才被加载的库。动态库可以被多个程序共享,节省内存和磁盘空间,并且可以更容易地更新库中的代码而不需要重新编译使用该库的所有程序。动态库通常以.so为文件后缀。
编译源文件为位置无关代码(Position Independent Code, PIC):使用 -fPIC-fpic选项编译源文件,生成目标文件。
 
     
       
     
gcc -fPIC -c source_file.c
-fPIC生成的代码可以被加载到内存中的任何位置,而 -fpic生成的代码在某些架构上可以更快地进行地址绑定,但可能不适用于所有平台。
创建动态库:使用 gcc-shared选项来指定生成动态库。
 
     
       
     
gcc -shared -o liblibrary_name.so object_file1.o object_file2.o ...
这里 -shared 选项告诉编译器生成一个动态库。
设置版本号:通常,动态库会有一个主版本号和次版本号。可以在库文件名中包含这些版本号。
 
     
       
     
gcc -shared -o liblibrary_name.so.1.0 object_file1.o object_file2.o ...ln -s liblibrary_name.so.1.0 liblibrary_name.so.1ln -s liblibrary_name.so.1 liblibrary_name.so
这里, liblibrary_name.so.1.0 是带有具体版本号的库文件,而 liblibrary_name.so.1 liblibrary_name.so 是符号链接,分别指向主版本和库的当前版本。
编译时链接:在编译程序时,使用 -L选项指定动态库的路径,使用 -l选项指定要链接的库。
 
     
       
     
gcc program.c -L/path/to/library -llibrary_name -o program
编译器会使用库文件中的符号来解析程序中的符号引用。
设置运行时库路径:确保动态链接器能找到动态库。可以通过设置 LD_LIBRARY_PATH环境变量来指定库的搜索路径。
 
     
       
     
export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH
或者,可以在系统级的库缓存中添加库的路径,使用 ldconfig 命令。
 
     
       
     
sudo ldconfig /path/to/library
运行程序 :现在可以运行编译好的程序,动态链接器会在程序启动时加载所需的动态库。
  • 动态库在程序运行时被加载,因此可执行文件的大小比使用静态库时小。
  • 动态库允许库的代码在内存中共享,这意味着所有使用同一动态库的程序都共享同一份代码,节省内存。
  • 动态库的更新只需要替换库文件,不需要重新编译使用该库的程序。
  • 动态库的使用增加了程序的依赖性,如果库文件被删除移动,程序可能无法运行。
  • 动态库的版本管理很重要,不兼容的库更新可能导致依赖它的程序崩溃。

一个简单的例子:

假设我们有一个简单的数学库,它提供两个函数:add 和 multiply。
编写源代码:首先,我们创建两个源文件 add.cmultiply.c

add.c:

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

multiply.c:

 
     
       
     
int multiply(int a, int b) { return a * b;}
编译源文件为共享对象 使用 gcc 编译这些源文件,并使用 -shared 选项生成共享对象(动态库)。
 
     
       
     
gcc -fPIC -shared -o libmath.so add.c multiply.c
这里, -fPIC 生成位置无关代码, -shared 指定生成动态库, libmath.so 是我们创建的动态库的名称。
设置版本号(可选):为了更好地管理动态库的版本,我们可以设置版本号。
 
     
       
     
mv libmath.so libmath.so.1ln -s libmath.so.1 libmath.so
这里, libmath.so.1 是带有具体版本号的库文件,而 libmath.so 是一个符号链接,指向当前版本。
现在,我们创建一个程序 main.c,它使用我们的数学库。
编写使用库的程序main.c 使用 addmultiply 函数。

main.c:

 
     
       
     
#include <stdio.h>
extern int add(int, int);extern int multiply(int, int);
int main() { int sum = add(3, 4); int product = multiply(3, 4);
printf("Sum: %d\n", sum); printf("Product: %d\n", product);
return 0;}
编译程序:在编译 main.c 时,我们需要指定动态库的路径和库名。但是,由于动态库在运行时才被加载,编译时只需要声明外部函数。
 
     
       
     
gcc main.c -o program -L. -lmath
    • -L. 指定了动态库的搜索路径(当前目录)。
    • -lmath 指定了要链接的库,链接器会查找 libmath.solibmath.so.1

设置运行时库路径:在运行程序之前,确保动态链接器能找到动态库。可以通过设置 LD_LIBRARY_PATH 环境变量来指定库的搜索路径。

 
     
       
     
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
运行程序 编译完成后,你可以运行生成的程序。
 
     
       
     
https://mp.weixin..com/program
输出应该是:
 
     
       
     
Sum: 7
Product: 12
如果一切设置正确,程序将成功运行,并在运行时动态加载 libmath.so 动态库。

想了解更多

赶紧扫码关注

到此这篇动态库和静态库的区别在哪里(静态库和动态库的概念)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 启动u盘 制作(启动u盘制作好了,镜像文件放哪)2025-05-07 17:00:04
  • 制作网站的代码(个人网站的制作代码)2025-05-07 17:00:04
  • 文件比较工具(文件比较工具 查重)2025-05-07 17:00:04
  • 使命召唤定位打开了无法获取位置(使命召唤定位打开了无法获取位置信息)2025-05-07 17:00:04
  • mt19937怎么用(mt199 mt799)2025-05-07 17:00:04
  • 网站查询ip反查(网站查询 ip)2025-05-07 17:00:04
  • u盘制作镜像安装系统(u盘制作镜像系统盘)2025-05-07 17:00:04
  • win32是什么意思(win32是什么文件夹)2025-05-07 17:00:04
  • win10虚拟机xp怎么联网(xp系统虚拟机怎么联网)2025-05-07 17:00:04
  • jflash命令行烧录S32K144(jflash命令行烧录S32K144)2025-05-07 17:00:04
  • 全屏图片