Linux:动态库和静态库的编译与使用

作者 : admin 本文共3676个字,预计阅读时间需要10分钟 发布时间: 2024-06-9 共2人阅读

目录

        1.前言

        2.静态链接库

        3.静态链接库生成步骤

        4.静态链接库的使用

        5.动态链接库

        6.动态链接库生成步骤

        7.动态链接库的使用

        8.动态链接库无法加载

        9.解决动态链接库无法加载问题


前言

        在《MinGW:从入门到链接库》博客中简单介绍了如何编译动态链接库和静态链接库,本篇博客将详细的对Linux下编译动态链接库和静态链接库以及使用进行讲解,刨析创建库文件的时候Linux做了哪些操作。本篇博客将从静态链接库讲起,再到动态链接库的讲解,并配上演示图片


静态链接库

        静态链接库是一组编译后的代码和资源,它们在编译时被整合到最终的可执行文件中。其静态链接库在不同系统的命名规则如下:

        1..Linux下的动态链接库的命名规则为lib+文件名+.a,所以Linux中以.a结尾的文件,一般可以视为静态链接库的文件

示例:libWild.a

        2.Windows下的动态链接库的命名规则为lib+文件名+.lib,所以以.lib结尾的文件,一般可以视为静态链接库的文件

示例:libWild.lib

        静态链接库的优缺点如下

                优点

                        1.库代码已经包含在可执行文件中,不需要携带额外的库文件

                        2.执行速度快,因为操作系统不需要在运行时解析外部库

                缺点

                        1.增加了可执行文件的大小,因为其静态链接库包含了所有代码

                        2.如果库更新,需要重新编译整个应用程序,编译时间长


静态链接库生成步骤

        在了解了静态链接库的特点以及不同系统下的命名方式后,我们需要着手生成一个静态链接库文件:

        1.使用-c命令生成汇编文件

//使用-c命令生成汇编文件
g++ -c -I "头文件路径" *.cpp

        2.使用ar命令打包生成静态链接库

//使用ar命令生成静态链接库
ar rcs 静态链接库名.a 汇编文件.o
 
//ar rcs libfun.a fun.o
//其中r代表替换.o文件,c代表库不存在则生成,s代表生成索引文件

        可参考下图生成静态链接库:

Linux:动态库和静态库的编译与使用插图

图1.生成静态链接库


静态链接库的使用

        当使用命令生成一个可用的静态链接库后,我们需要将其源文件与静态链接库放到同一个目录中,然后根据头文件编写代码, 对静态库中的函数进行调用

        1.将源文件与静态链接库链接产生可执行文件       

//方法1
g++ 源文件.o -o 可执行文件名 静态链接库路径
 
//方法2
g++ 源文件.o -o 可执行文件名 -L静态链接库路径
 
//方法3,其中静态链接库名为除去lib和.a的名称
//例如libfun.a,其静态链接库名就为fun
g++ 源文件.o -o 可执行文件名 -L静态链接库路径 -l静态链接库名

Linux:动态库和静态库的编译与使用插图(1)

图2.多种方法生成静态链接库可执行文件

        PS:如果提示找不到头文件的定义,需要使用-L和-l命令,其含义如下:

-L: 指定库所在的路径
-l: 指定库的名字, 需要去掉前缀lib和后缀.a

示例:g++ Code.o -o Code -L ./ -l fun
//其中fun为静态链接库libfun.a


动态链接库

        动态链接库在程序运行时被加载,而不是在编译时。它允许多个程序共享同一份库代码。其命名规则如下:

        1..Linux下的动态链接库的命名规则为lib+文件名+.so,所以Linux中以.so结尾的文件,一般可以视为动态链接库的文件

示例:libWild.so

        2.Windows下的动态链接库的命名规则为lib+文件名+.dll,所以以.dll结尾的文件,一般可以视为动态链接库的文件

示例:libWild.dll

        动态链接库的优缺点如下:

                优点

                        1.减少了内存占用,因为多个程序可以共享同一份库代码

                        2.库的更新只需要更新DLL文件本身,不需要重新编译使用该库的应用程序

                        3.可以动态加载和卸载,提供更高的灵活性

                缺点

                        1.运行时需要加载库,可能会稍微增加启动时间

                        2.如果库文件被其他程序占用或损坏,可能会导致程序无法正常运行


动态链接库生成步骤

        在了解了动态链接库的特点以及不同系统下的命名方式后,我们需要着手生成一个动态链接库文件:

        1.使用-c命令生成汇编文件

//使用-c命令生成汇编文件
g++ -c -I "头文件路径" *.cpp

        2.使用-shared命令生成动态链接库

//使用-shared命令生成动态链接库
g++ -o 动态链接库.dll -I "头文件路径" -fPIC -shared *.cpp
 

Linux:动态库和静态库的编译与使用插图(2)

图3.生成动态链接库


动态链接库的使用

        当使用命令生成一个可用的动态链接库后,我们需要将其源文件与动态链接库放到同一个目录中,然后根据头文件编写代码, 对动态库中的函数进行调用

        1.将源文件与静态链接库链接产生可执行文件   

//方法1
g++ 源文件.o -o 可执行文件名 动态链接库路径
 
//方法2
g++ 源文件.o -o 可执行文件名 -L动态链接库路径
 
//方法3,其中动态链接库名为除去lib和.dll的名称
//例如libfun.dll,其静态链接库名就为fun
g++ 源文件.o -o 可执行文件名 -L动态链接库路径 -l动态链接库名

Linux:动态库和静态库的编译与使用插图(3)

图4.多种方法生成动态链接库可执行文件

        PS:倘若出现未定义的头文件等错误,则可以参考静态链接库生成可执行文件的方法,使用-L与-l命令指定库地址


动态链接库无法加载

        首先为啥这种无法加载的问题会出现在动态链接库?而不是静态链接库。是由于在生成可执行文件时,静态链接库会被打包到可执行程序中。当程序执行时,静态链接库库中的代码也会加载到系统的内存当中,因此不会出现静态链接库找不到无法被加载的问题

        而动态链接库在打包时只是检测库文件是否存在,存在则打包,不存在则不打包。所以动态链接库并没有被打包到可执行文件中,只是在文件中记录了动态链接库的名字。所以当程序执行时,会存在动态链接库无法加载的问题


解决动态链接库无法加载问题

        在Linux系统中,我们可以使用动态链接器来解决这个问题。动态链接器是一个在程序运行时负责链接程序与动态链接库的程序,其寻找链接库的步骤如下:

                1.编译时指定路径:如果编译时通过特定的编译器选项(如在Linux中的-Wl,-rpath)指定了库的运行时搜索路径,动态链接器会首先在这些路径中搜索库

                2.环境变量:动态链接器会检查环境变量来确定库的搜索路径。例如,在Linux系统中,LD_LIBRARY_PATH环境变量可以添加额外的库搜索路径;在Windows系统中,PATH环境变量用于搜索.dll文件

                3.标准库目录:操作系统会预定义一些标准目录来存放系统级的库。例如,在Linux中,/lib/usr/lib是常见的库目录;在Windows中,系统目录(如C:\Windows\System32)是搜索.dll文件的地方

                4.可执行文件所在目录:动态链接器会搜索可执行文件所在的目录

        解决方法如下:

                1: 将库路径添加到环境变量LD_LIBRARY_PATH中

                        1.找到相关的配置文件

~/.bashrc:用户路径,只对当前用户有效
/etc/profile:系统路径,对所有用户有效

                        2.修改配置文件

#添加动态链接库路径
export LD_LIBRARY_PATH =$LD_LIBRARY_PATH :动态链接库的绝对路径

Linux:动态库和静态库的编译与使用插图(4)

图5.将库路径添加到环境变量LD_LIBRARY_PATH

                        3.执行更新命令

source ~/.bashrc    //用户路径
source /etc/profile //系统路径

//source命令用于执行指定文件

                2.更新/etc/ld.so.cache文件

                        1.打开ld.so.cache文件

sudo vim /etc/ld.so.conf

                        2.更新 /etc/ld.so.conf中的数据到 /etc/ld.so.cache 中

sudo ldconfig   

Linux:动态库和静态库的编译与使用插图(5)

图6.更新/etc/ld.so.cache文件


        PS:关于动态链接库和静态链接库的生成与使用还需要更多的实践才能更灵活的运用,所以不要停留在纸上谈兵的阶段,计算机专业并不是什么文科,不需要通篇背诵,多实操,多练,多发现问题,多解决问题

本站无任何商业行为
个人在线分享 » Linux:动态库和静态库的编译与使用
E-->