🔦要理解以下技术术语,先描述一些东西(即什么是库?)可能会有所帮助。 以及如何运作?
问:什么是图书馆?
答:在C语言和其他语言中,来自许多不同目标文件的编译代码(都塞入单个文件中)称为库。 库具有可移植性和可扩展性,是团队和大型项目的理想选择。 例如,如果我要用C创建一个文字处理程序,我将需要许多处理字符串的函数,以使我的团队生活更轻松,我应该创建一个包含我们可能使用的每个函数的库,例如,字符串长度函数,字符串连接函数等。
问:图书馆如何运作?
答:它的工作原理是允许最终用户在运行时或编译时通过其目标文件的符号链接功能-这取决于您创建的库的类型。 有两种: 静态和动态 。
这是有关stackoverflow的静态库的更详细说明:
静态库纯粹是
.o文件的集合,放在一个类似zip文件的存档中(无压缩)。 当您使用它进行链接时,链接器将在库中搜索在主程序中提供任何缺失符号的.o文件,然后拉入这些.o文件进行链接,就好像它们已包含在命令行中一样,例如.o文件在您的主程序中。 此过程是递归应用的,因此,如果从库中拉入的任何.o文件都具有未解析的符号,则将再次在库中搜索提供定义的其他.o文件。
问:什么是C中的动态库?
答:这是一个在运行时编译并存储在可执行文件中的函数库。
💡 共享库是动态库的别名,因此从现在开始我们将称为动态库共享库。
以下是有关Himanshu Arora中共享库的详细说明:
共享库是可以在运行时链接到任何程序的库。 它们提供了一种使用可以加载到内存中任何位置的代码的方法。 加载后,共享库代码可被任意数量的程序使用。 因此,通过这种方式,程序的大小(使用共享库)和内存占用空间可以保持较低,因为许多代码以共享库的形式保持通用。
问:共享库和静态库有什么区别?
答:有几个区别-这是最重要的区别:
- 静态链接比动态链接占用更多的空间 ,因为每个单独的可执行文件中都包含库中的每个目标文件。 因为并非每个可执行文件都需要每个功能,所以静态链接往往会浪费空间。 共享库使您可以从库中选择要使用的功能。 有关稍后如何实现的更多信息。
- 共享库以.so结尾,并在运行时访问,而静态库以.a结尾,并在编译时访问。
问:使用静态库有什么优势?
答:最终的可执行文件包含所有必需的库函数及其目标文件。
问:静态库有哪些缺点?
答:可执行文件的大小通常很大
问:使用共享库有什么优势?
答:可执行文件的大小通常较小。 可以更有效地执行几个具有相同库功能的程序,例如,即使修改了源代码,也不必再次编译源代码。
问:共享库有哪些缺点?
答:可执行文件不是自我维持的,因为它们仅包含指向每个函数与实际目标文件的符号链接。 如果共享库被更改,则使用它的可执行文件可能无法正常运行,因为动态链接变得不兼容。
be我敢打赌,您现在一定会对如何创建一个库感到好奇,方法如下:
- 对于静态库,请在此处查看我创建的上一篇文章。
- 对于共享库,请继续阅读。
要创建共享库,请使用以下命令:
gcc -g -fPIC -Wall -Werror -Wextra -pedantic * .c -shared -o NAMEOFLIBRARY.so
让我们分解以上命令:
- gcc是您的编译器,它通过一系列步骤来创建可执行文件,具体取决于传递给它的选项
- 传递给gcc时,’- g ‘标志包含调试信息,该信息可用于多种用途,在这种情况下,它会为可执行文件的每个部分生成符号,从而使编译器更容易查看
- “ -fPIC ”标志允许您指定可以在任何部分遍历的库,这表明该库是动态的。 如果您好奇, fPIC代表“ 位置独立代码”
- ‘ -Wall -Werror -Wextra -pedantic ‘部分使用严格的警告来编译您的可执行文件,这不是必需的,但是在这种情况下,这被认为是很好的约定。
- ‘ * .c ‘表示您希望一次编译所有.c文件,而不是分别指定每个程序的名称
- -shared标志是创建共享库的原因,在shared标志允许您将库命名为任意名称后指定-o ,请注意,需要.so扩展名
创建库后,可以通过创建一个C文件来使用它,该文件利用共享库中的功能之一,以字符串长度为例,以下是可以使用的主文件:
#include
#include“ header.h” int main(void)
{
char * s =“您正在学习动态编程”;
printf(“字符串s中有%d个字符。\ n”,_ strlen(s));
返回(0);
}
要使用共享库的自定义函数对其进行编译,请键入:
gcc -Wall -pedantic -Werror -Wextra -L。 main.c -NAMEOFLIBRARY -o len
- 在上面,您指定了主程序的名称,库的名称以及您要运行的可执行文件的输出名称。
在实际执行“ len ”之前,我们需要做几件事,因为动态库需要包含在LD_LIBRARY_PATH 环境变量,以将动态库添加到LD_LIBRARY_PATH 变量,只需键入:
导出LD_LIBRARY_PATH =。:$ LD_LIBRARY_PATH
- 这会将您当前的工作目录添加到包含共享库的
LD_LIBRARY_PATH变量中。
现在,您应该可以在终端中运行./len并接收字符串s的长度,如下所示:


- 动态库与共享库相同,并且通常比静态库更可取,因为它们的大小较小且更具针对性
- 如果您知道要使用给定库中的每个函数,则静态库有时会更好,它们也可以更快但效率更低
- 务必记住将共享库所在的目录添加到
LD_LIBRARY_PATH变量中,否则您将无法使用库 - 使用任何类型的库都取决于可执行文件的编译
- 当您需要大量的可移植功能或团队合作时,任何类型的库都是有益的
看到任何更正吗? 随时通过@wn_gc在Twitter上与我联系,或通过电子邮件在a.catawampus@gmail.com与我联系。