我正在学习C语言中的静态和动态库以及如何制作它们。
一直困扰我的一件事是:
假设通过执行mylibrary
,文件正在使用库#include <mylibrary.h>
。
这是否意味着C库与匹配的 text 头文件一起分发?还是mylibrary.h
从二进制库文件以某种方式神奇地导出了?
这在不同方法之间是否有所不同,或者库是静态的还是动态的?
答案 0 :(得分:1)
是的,根据平台的不同,您将获得更多文件来分发。这是一个非常混乱的故事。至少,该库是静态的还是动态的(除了链接程序参数外)都没有关系。
头文件是必需的,因为已编译的二进制文件包含的信息不足以供编译器使用。由于某些基于平台的差异,因此C二进制文件通常仅具有足够的元数据以通过函数名称标识函数和全局变量。该元数据不包括参数的类型(或计数),返回类型,结构或联合定义,全局变量的类型或大小等。所有这些信息通常都编码在与库一起分发的标头中。 (方便地,这也意味着对开发人员而言,标头中不存在的任何内容都被隐藏了;这是您可以在库中创建非公共函数的原因,用户不应直接调用该函数。)
在某些平台上,二进制甚至不包含函数名称。而是通过函数在“普通表”中的位置来引用函数。在这些平台上,该库必须附带一个标头,可执行的二进制文件和一个附加文件,该文件将从标头中的函数名称转换为序表中的函数索引,例如“ void hello(void) ”可能是链接器的“序表中索引3处的函数”。
相反,包含标头通常不会链接到它附带的库。这在某些平台(例如Windows)上是可能的,在该平台上,可以在标头中放一些特殊的编译器指令,并告诉链接器链接到某些库,但这不是标准行为,您不能指望它是在任何其他平台上的现实。
上层和下层是模块,它们为链接二进制文件提供了更好的用户体验。模块是另一个可以与二进制文件一起打包的文件,上面写着“这里是我的所有标头,这里是我的所有库”。使用模块,可以编写“ import MyLibrary;”之类的东西。它将为您提供所有所需的标题和所有链接器参数。我相信还没有C标准模块。 C ++随C ++ 20一起发展。