C语言中的动态库

在编写C代码时,库是节省时间的好方法。 通过使用库,您可以将函数保存到一个方便的程序包中,而该程序包可以在项目的不同部分或不同的项目中一起传输,而不是一遍又一遍地为多个项目编写相同的代码。

在上一篇文章中,我讨论了在C中创建和使用静态库的基础。静态库的代码在编译时被锁定在程序中,这既有其优点,也有其缺点。 一方面,不必依赖另一个文件可以使程序执行得更快(由于代码已经是正在运行的二进制文件的一部分)和更可靠地执行。 但是,由于代码是可执行文件的一部分,因此更新库中包含的所有功能(无论是出于效率还是为了修正错误)都需要重新编译整个程序。

动态库包含的功能与静态库相似,不同之处在于动态库的代码与最终的可执行文件是分开的。 这允许一些有趣的功能,例如多个程序能够引用一个中央库。 能够在一个文件中更新由多个其他可执行文件引用的单个功能是一个非常有效的过程。 另一个好处是可以对程序进行小的更新,而无需完全重新编译。 至于底片,需要多个文件来运行程序可能会有些危险。 动态库是单独的文件,而不必担心单个可执行文件,它们可以与预期位置分开。 另一个缺点是,可能破坏的不仅仅是您要修复的程序。 动态库中的函数调用也很慢,因为它们在可执行文件之外。

首先,打开您选择的终端,并为自己准备一个充满功能文件的文件夹,您将来可能会希望使用。 然后,有几个命令可以用来创建我们的库。

  1. gcc -c -fPIC *.c -o my_lib_output.o :此命令将从当前工作目录中所有.c文件中生成一个目标文件。 第一个-c标志告诉GCC这些文件应在不经过链接过程的情况下进行编译。 -fPIC是一个多部分标志。 它告诉GCC禁止在输出文件中生成P rohibit线标记,除了预处理外还输出I nclude指令,除非处理它们,否则不要丢弃它们。 下一部分*.c使用称为通配符扩展的过程(由外壳程序执行),以便包括所有以“ .c”结尾的文件。 最后, -o标志创建一个名为“ my_lib_output.o”的输出文件。
  2. gcc my_lib_output.o -shared -o libmydynamic.so :有了我们新生成的输出文件,运行此命令将使用-shared标志编译.o文件,将其标记为动态库。 我们最终的动态库文件将称为“ libmydynamic.so”!
  3. export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH :最后,我们需要告诉我们的计算机在哪里寻找这个新创建的库。 export命令允许您更改计算机上的全局变量。 LD_LIBRARY_PATH是我们的计算机在运行可执行文件时将查找动态库的位置。 要添加目录,我们可以将当前目录分配为path变量的一部分。 由于PATH变量的结构是可预测的( dir/ectory/:dir/ectory/two… ),因此我们可以将当前工作目录(包含在$PWD全局变量中)附加到库路径的开头,以确保在其他目录中可能具有相同名称的其他库之前找到我们的库版本。

尽管可以将前两个命令压缩到gcc -shared -o libmydynamic.so -fPIC *.c ,但将其拆分可以更全面地了解在此过程中创建的文件。

静态库审查:

我在上一篇文章中详细讨论了静态库的创建过程,但总而言之,再次:

  1. 以与创建动态库的第一步相同的方式创建输出文件。
  2. 使用命令ar -rc libstatic.a *.c将输出文件归档为“ .a”文件。
  3. 包括在程序的最终编译过程中创建的静态库。

为了创建一个能够读取动态库的可执行文件,在编译程序时需要在gcc命令中添加-l[library]标志。 在上下文中,我们的标志将如下所示:

-lmydynamic
它将自动在文件名中添加“ lib-”和“ -.so”前缀和后缀,告诉程序在我们的程序中搜索“ libmydynamic.so”
LD_LIBRARY_PATH变量。 如果该库在那里,我们的程序应该运行顺利!