LIB不需要其他依赖项,但DLL是必需的

时间:2010-09-11 14:59:06

标签: c++ dll static-libraries

我有一个框架(在C ++中),它依赖于一些第三方库。当我编译静态版本的框架时,不需要其他依赖项,也就是说,不需要第三部分库的lib文件。当我编译与DLL相同的框架时,现在需要额外的依赖项,否则我会得到链接错误。我可以猜测为什么会发生这种情况,但想要了解具体的答案/解释来了解正在发生的事情。

编辑:为了澄清,我正在开发一个框架,可以编译为libdll以及然后在(n)(可执行)项目中。将框架编译为lib并使用第三方库中的函数时,我不需要其他依赖项。但是,现在使用lib文件(即框架)的项目必须包含第三方lib文件。当我将框架编译为dll时,它会给我链接错误,除非我指定框架在技术上依赖的第3部分库。例如:我有一些类可以在Ogre3D中调用功能。这些类编译为lib文件。编译OgreMain.lib类时,我不需要链接lib。另一方面,当我编译相同类的dll版本时,我现在需要链接到OgreMain.lib

4 个答案:

答案 0 :(得分:3)

如果您有一个静态库(.lib文件),它只是一个或多个目标文件(.obj)的集合,那么链接器只会将该代码添加到您的一个可执行文件中。您可以告诉链接器通过命令行开关,IDE配置设置或甚至#pragma(具体取决于您的环境和编译器)来执行此操作。

在DLL中链接时,需要为链接器提供一些代码,以便在调用其中一个DLL函数时调用。通常,这是使用与.dll同名的文件完成的,除非它是.lib。该.lib中的代码以与上述相同的方式链接到您的程序中,但是当您调用它时,它会加载DLL(如果尚未加载),然后调用正确的函数。

还有其他方法可以处理DLL链接(例如,.def文件或.NET中的#using语句),但这似乎就是你所说的。


回答您的问题澄清:

问题是.lib不是最终产品。它只是稍后当链接器将所有函数调用连接到函数地址时使用的目标代码的聚合。

另一方面,DLL是最终产品,因此链接器要求所有函数和变量都连接到实际地址。

我说的有点不精确,但你明白了。

答案 1 :(得分:0)

静态库可以包含其他静态库,提供单个lib链接

DLL可以包含静态库,提供单个DLL来链接。

依赖于其他DLL的DLL或静态库无法组合它们,因此您的可执行文件必须显式链接到其他DLL。

答案 2 :(得分:0)

当您链接到LIB时,它会将您实际使用的所有符号/函数添加到可执行文件中。你不使用的那些不会被添加。当您链接到DLL时 - 外部库中的所有代码都会被加载。如果这个附加代码(您不使用的代码)依赖于更多的外部库,您也需要提供这些代码。

一个例子:您想要使用网络库中的ip类。 ip类不依赖于其他库。网络库中的其他功能取决于其他外部库。如果您将网络库链接为LIB,则只需链接ip class - >你不需要其他库,因为其他代码不会被链接。当你使用DLL时,dll中的所有代码都需要实例化 - >所以你需要提供其他外部库。

答案 3 :(得分:0)

构建DLL更像是构建应用程序而不是库。构建应用程序和DLL之间的区别在于可以调用的内容。在一个应用程序中,所有未使用的符号都可以在构建中被丢弃,但是在DLL中你不能剥离未使用的符号 - 这些符号都是...... 如果能够调用DLL链接的所有符号,您会在静态库中发现相同的链接问题。