静态库,静态链接动态库和动态链接动态库的.lib文件内部是什么?
为什么在动态链接的动态库中不需要.lib文件,而且在静态链接中,.lib文件只不过是带有所有方法的.obj文件。这是对的吗?
答案 0 :(得分:117)
对于静态库,.lib文件包含库的所有代码和数据。然后链接器识别它需要的位并将它们放在最终的可执行文件中。
对于动态库,.lib文件包含库中导出的函数和数据元素的列表,以及有关它们来自哪个DLL的信息。当链接器构建最终的可执行文件时,如果使用库中的任何函数或数据元素,则链接器会添加对DLL的引用(导致它由Windows自动加载),并将条目添加到可执行文件的导入表中,以便对该函数的调用被重定向到该DLL。
您不需要.lib文件来使用动态库,但如果没有,您无法将DLL中的函数视为代码中的常规函数。相反,您必须手动调用LoadLibrary
以加载DLL(并在完成后加FreeLibrary
),并GetProcAddress
以获取DLL中函数或数据项的地址。然后,必须将返回的地址强制转换为适当的指向函数的指针才能使用它。
答案 1 :(得分:12)
我发现来自汉斯的answer以下内容也很有用。它清除了有两种类型的lib文件的空气。
LIB文件用于构建程序,它只存在于您的构建中 机器,你不发货。有两种。静态链接 库是一包.obj文件,收集到一个文件中。该 链接器在需要解析时从文件中选择任何代码块 外部标识符。
但是与DLL更相关,LIB文件也可以是导入库。 它是一个简单的小文件,包含DLL的名称和 DLL导出的所有函数的列表。你需要提供 当你构建一个使用DLL的程序时它会链接到链接器 知道外部标识符实际上是导出的函数 DLL。链接器使用导入库向条目添加条目 EXE的导入表。然后由Windows使用 运行时以确定需要加载哪些DLL来运行程序。
答案 2 :(得分:7)
在静态库中,lib文件包含库提供的函数的实际目标代码。在共享版本(您称之为静态链接的动态库)中,只有足够的代码可以在运行时建立动态链接。
我不确定“动态链接动态库”(以编程方式加载)。在这种情况下你甚至用.lib链接吗?
编辑:
来晚了一点,但不,你没有链接.lib。好吧,你用libloaderex链接到lib。但是对于你正在使用的实际库,你通过C函数指针提供自己的绑定,而loadlibrary则填充它们。
以下是摘要:
Linking ǁ Static | DLL | LoadLibrary =========ǁ===============|======================|=================== API code ǁ In your com- | In the DLL | In the DLL lives ǁ piled program | | ---------ǁ---------------|----------------------|------------------- Function ǁ Direct, may | Indirect via table | Indirect via your calls ǁ be elided | filled automatically | own function ptrs ---------ǁ---------------|----------------------|------------------- Burden ǁ Compiler | Compiler/OS | You/OS
答案 3 :(得分:5)
链接器读取lib文件,并在执行期间使用dll文件。 lib文件在执行期间基本上没用,并且链接器无法读取 dll文件(除非可能以与此处无关的方式)。
使用lib文件进行静态和动态链接之间的差异可能会让人感到困惑,但如果您了解一点历史,那么它就会变得非常清楚。
最初只有静态库。对于静态库,.lib文件包含obj文件。每个obj文件是一个且只有一个编译器源代码输入文件的输出。 lib文件只是相关obj文件的集合,就像将obj文件放在目录中一样。这本质上是一个lib文件,一个obj文件库。对于静态链接,可执行文件使用的所有obj文件都合并到一个文件中。将其与动态链接进行比较,其中可执行文件位于与其使用的其他代码分开的文件中。
为了实现动态链接,Microsoft修改了lib文件的使用,使得它们引用dll文件而不是obj文件中的位置。除此之外,静态链接库中的所有信息都与动态链接相同。除了动态链接的lib文件指定dll文件外,它们与它们中的信息完全相同。
答案 4 :(得分:1)
在dll中的“东西”就像在exe中一样(可以有任何类型的数据,导入,导出,读/写/可执行部分),但区别在于exe文件只导出入口点(函数)但是dll导出一个/多个函数。