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
5 回答
我发现以下来自Hans的answer在这里也很有用 . 它清除了有两种类型的lib文件的空气 .
对于静态库,.lib文件包含库的所有代码和数据 . 然后,链接器识别它需要的位并将它们放入最终的可执行文件中 .
对于动态库,.lib文件包含库中导出的函数和数据元素的列表,以及有关它们来自哪个DLL的信息 . 当链接器构建最终的可执行文件时,如果使用库中的任何函数或数据元素,则链接器会添加对DLL的引用(导致它由Windows自动加载),并将条目添加到可执行文件的导入表中,以便对函数的调用被重定向到该DLL .
您不需要.lib文件来使用动态库,但如果没有它,则无法将DLL中的函数视为代码中的常规函数 . 相反,您必须手动调用
LoadLibrary
以加载DLL(并在完成时FreeLibrary
)和GetProcAddress
以获取DLL中函数或数据项的地址 . 然后,必须将返回的地址强制转换为适当的指向函数的指针才能使用它 .在静态库中,lib文件包含库提供的函数的实际对象代码 . 在共享版本(您称之为静态链接动态库)中,只有足够的代码可以在运行时 Build 动态链接 .
我不确定“动态链接动态库”(以编程方式加载) . 在这种情况下你甚至链接.lib?
编辑:
来晚了一点,但不,你没有链接.lib . 好吧,你用libloaderex链接到lib . 但对于您正在使用的实际库,您可以通过C函数指针提供自己的绑定,并使用loadlibrary填充它们 .
这是一个总结:
链接器读取lib文件,并在执行期间使用dll文件 . lib文件在执行期间基本上是无用的,并且链接器不能使用dll文件(除了这里不相关的方式) .
使用lib文件进行静态和动态链接之间的差异可能会令人困惑,但如果你了解一点历史,那么它就会变得非常清楚 .
最初只有静态库 . 对于静态库,.lib文件包含obj文件 . 每个obj文件是一个且只有一个编译器源代码输入文件的输出 . lib文件只是相关obj文件的集合,就像将obj文件放在目录中一样 . 这本质上是一个lib文件,一个obj文件库 . 对于静态链接,可执行文件使用的所有obj文件都合并到一个文件中 . 将其与动态链接进行比较,其中可执行文件位于与其使用的其他代码分开的文件中 .
为了实现动态链接,Microsoft修改了lib文件的使用,使得它们引用dll文件而不是obj文件中的位置 . 除此之外,静态链接库中的所有信息都与动态链接相同 . 它们与它们中的信息完全相同,只是动态链接的lib文件指定了dll文件 .
在dll中是像exe中的“东西”(可以有任何类型的数据,导入,导出,读/写/可执行部分),但区别在于exe文件只导出入口点(函数)但是dll导出一个/很多功能 .