当前位置: 首页 > 科技观察

静态链接库如何在Linux上工作

时间:2023-03-20 10:47:51 科技观察

了解如何使用静态链接库将多个C目标文件组合成一个可执行文件。当使用用C编写的应用程序时,您通常有多个源代码文件,但最终您需要将它们编译成一个可执行文件。您可以通过两种方式做到这一点:创建静态库或动态库(也称为共享库)。从它们的创建和链接方式来看,它们是两种不同类型的库。您选择使用哪种方法取决于您的特定场景。在上一篇文章中,我演示了如何创建动态链接的可执行文件,这是一种更通用的方法。在本文中,我将解释如何创建静态链接的可执行文件。使用静态库链接器链接器是一个组合程序的各个部分并为它们重新组织内存分配的命令。链接器的作用包括:整合一个程序的所有部分,计算出一个新的内存组织结构,使所有部分结合起来,还原内存地址,使程序可以在新的内存组织结构下运行这些功能创建了一个可运行的程序,名为可执行。静态库是通过将程序中所有依赖的库模块复制到最终的可执行映像中来创建的。链接器将链接静态库作为编译过程的最后一步。可执行文件是通过解析外部引用并将库例程与程序代码相结合来创建的。创建目标文件下面是一个静态库及其链接过程的示例。首先,创建带有标识这些函数的标志的头文件mymath.h:intadd(inta,intb);intsub(inta,intb);intmult(inta,intb);intdivi(inta,intb);使用这些函数定义来创建add.c、sub.c、mult.c和divi.c文件。我打算将所有代码放在一个代码块中,请将其分成四个文件,如注释所示://add.cintadd(inta,intb){return(a+b);}//sub.cintsub(inta,intb){return(a-b);}//mult.cintmult(inta,intb){return(a*b);}//divi.cintdivi(inta,intb){return(a/b);现在,使用GCC生成目标文件add.o、sub.o、mult.o和divi.o:objectfile,有时也称为“objectfile”。在这方面,有一些翻译上的混淆。译名为“objectfile”的翻译方式比较流行,本文中使用的就是这种译法。)$gcc-cadd.csub.cmult.cdivi.c-c选项跳过链接步骤,只创建目标文件.创建一个名为libmymath.a的静态库。接下来,删除不再需要的目标文件。(请注意,使用trash命令比使用rm命令更安全。)$arrslibmymath.aadd.osub.omult.odivi.o$trash*.o$lsadd.cdivi.clibmymath.amult.cmymath.hsub.c您现在已经创建了一个名为libmymath的简单数学示例库,您可以在你的C代码。当然,也有非常复杂的C库,这是他们开发人员生产最终产品的过程,你和我可以在C代码中安装和使用。接下来,在一些自定义中使用你的数学库m代码,然后链接到它。创建静态链接的应用程序假定您已经编写了数学运算命令。创建一个名为mathDemo.c的文件并将这些代码复制粘贴到其中:#include#include#includeintmain(){intx,y;printf("请输入两个数\n");scanf("%d%d",&x,&y);printf("\n%d+%d=%d",x,y,添加(x,y));printf("\n%d-%d=%d",x,y,sub(x,y));printf("\n%d*%d=%d",x,y,mult(x,y));if(y==0){printf("\n分母为零所以不能进行除法\n");退出(0);}else{printf("\n%d/%d=%d\n",x,y,divi(x,y));返回0;注意:第一行是一个include语句,它按名称引用您自己的libmymath库。为mathDemo.c创建一个名为mathDemo.o的目标文件:$gcc-I。-cmathDemo.c-I选项告诉GCC搜索它后面列出的头文件。在本例中,您用一个点(.)指定当前目录。链接mathDemo.o和libmymath.a以生成最终的可执行文件。这里有两种方法可以告诉GCC这个。您可以指向文件:$gcc-static-omathDemomathDemo.olibmymath.a或者,您可以指定库的路径和名称:$gcc-static-omathDemo-L。mathDemo.o-lmymath在下面的示例中,-lmymath选项告诉链接器链接目标文件mathDemo.o和目标文件libmymath.a以生成最终的可执行文件。-L选项指示链接器在下面的参数中查找库(类似于您使用-I所做的)。使用file命令分析结果,验证它是静态链接的:$filemathDemomathDemo:ELF64-bitLSBexecutable,x86-64...staticallylinked,withdebug_info,notstripped使用ldd命令,你会看到可执行文件可执行文件不是动态链接的:$ldd./mathDemo不是动态可执行文件您还可以检查mathDemo可执行文件的大小:$du-h./mathDemo932K./mathDemo在我之前帖子的示例中,动态链接可执行文件仅占24K大小。运行此命令以查看它的实际效果:$./mathDemo输入两个数字10510+5=1510-5=510*5=5010/5=2看起来令人满意!何时使用静态链接动态链接可执行文件通常优于静态链接可执行文件,因为动态链接使应用程序的组件保持模块化。如果一个库收到一个关键的安全更新,它可以很容易地被修补,因为它存在于应用程序之外。当您使用静态链接时,库的代码“隐藏”在您创建的可执行文件中,这意味着每次库更新时(相信我,您会有更好的东西),只有一个修复方法是重新编译并分发一个新的可执行文件。但是,如果一个库的代码存在于一个与它所使用的代码相同的可执行文件中,或者存在于一个不会接收任何更新的专用嵌入式设备中,那么静态链接将是一个可接受的选项。