LIB 不需要额外的依赖项,但 DLL 需要额外的依赖项
我有一个框架(C++),它依赖于一些第三方库。当我编译静态版本的library框架时,不需要额外的依赖,即不需要第三方库的lib
文件。当我将相同的框架编译为 DLL 时,现在需要额外的依赖项,否则会出现链接错误。我可以猜测为什么会发生这种情况,但想要一个具体的答案/解释以了解发生了什么。
编辑:为了澄清,我正在开发一个框架,可以编译为lib
和dll
,然后 em> 用于(n)(可执行)项目。将框架编译为 lib
并使用第三方库中的函数时,我不需要额外的依赖项。但是,现在使用 lib
文件(即框架)的项目必须包含第 3 方 lib
文件。当我将框架编译为 dll
时,除非我指定框架在技术上依赖的第三部分库,否则它会给我链接错误。例如:我有一些类从 Ogre3D 中调用功能。这些类被编译为 lib
文件。编译类的 lib
时,我不需要链接到 OgreMain.lib
。另一方面,当我编译相同类的 dll
版本时,我现在需要链接到 OgreMain.lib
I have a framework (in C++) which is dependent on a few third party libraries. When I compile a static version of the library framework, no additional dependencies are needed, that is, the lib
files of the third part libraries are not needed. When I compile the same framework as a DLL
, additional dependencies are now needed otherwise I get linking errors. I can guess as to why this is happening but would like a concrete answer/explanation to understand what is happening.
EDIT: Just to clarify, I am developing a framework which can be compiled as a lib
and as a dll
and then used in a(n) (executable) project. When compiling the framework as a lib
and using functions from a third party library, I don't need additional dependencies. However, a project that now uses the lib
file (which is the framework) must include the 3rd party lib
files. When I compile the framework as a dll
it gives me linking errors unless I specify the 3rd part libraries the framework is technically dependent on. For example: I have a few classes that call functionality from within Ogre3D. These classes are compiled as a lib
file. I don't need to link against OgreMain.lib
when compiling a lib
of the classes. On the other hand, when I am compiling a dll
version of the same classes, I now need to link against OgreMain.lib
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您有一个静态库(.lib 文件)时,它只是一个或多个目标文件 (.obj) 的集合,链接器只是将该代码添加到一个可执行文件中。您可以通过命令行开关、IDE 配置设置甚至 #pragma(具体取决于您的环境和编译器)告诉链接器执行此操作。
当您链接到 DLL 时,您需要为链接器提供一些代码,以便在调用其中一个 DLL 函数时调用。通常,这是通过与 .dll 同名的文件来完成的,但它是 .lib。该 .lib 中的代码以与上述相同的方式链接到您的程序中,但是当您调用它时,它会加载 DLL(如果尚未加载),然后调用正确的函数。
还有其他方法可以处理 DLL 链接(例如,.def 文件或 .NET 中的 #using 语句),但这似乎就是您所讨论的。
回应您的问题澄清:
问题是 .lib 不是最终产品。它只是稍后当链接器将所有函数调用连接到函数地址时使用的目标代码的聚合。
另一方面,DLL 是最终产品,因此链接器要求所有函数和变量都连接到实际地址。
我说得有点不准确,但你明白我的意思。
When you have a static library (a .lib file), which is just a collection of one or more object files (.obj), the linker just adds that code to yours in one executable. You can tell the linker to do this via a command line switch, an IDE configuration setting, or perhaps even a #pragma (specifics depend on your environment and compiler).
When you link in a DLL, you need to give the linker some code to call when you invoke one of the DLLs functions. Usually, this is done with a file of the same name as the .dll, save that it is a .lib. The code in that .lib is linked into your program the same way as described above, but when you call it, it loads the DLL (if not already loaded) and then invokes the proper function.
There are other ways to handle DLL linking (for instance, .def files or #using statements in .NET), but this seems to be what you're talking about.
Responding to your question clarification:
The issue is that a .lib is not a final product. It is just an aggregation of object code to be used later when a linker connects all your functions calls to function addresses.
A DLL, on the other hand, is a final product, and so the linker requires all functions and variables be connected to actual addresses.
I'm speaking a bit imprecisely, but you get the idea.
静态库可以包含其他静态库,提供单个库来链接
。 DLL 可以包含静态库,提供单个 DLL 来链接。
依赖于其他 DLL 的 DLL 或静态库无法将它们组合起来,因此您的可执行文件必须显式链接到其他 DLL。
A static library can include other static libraries, providing a single lib to link
A DLL can include static libraries, providing a single DLL to link.
A DLL or static library with dependencies on other DLLs has no way to combine them so your executable must explicitly link to those other DLLs.
当您链接到 LIB 时,它会将您实际使用的所有符号/函数添加到可执行文件中。您不使用的不会被添加。当您链接到 dll 时 - 外部库中的所有代码都会被加载。如果此附加代码(您不使用的代码)取决于更多外部库,您也需要提供这些库。
一个例子:您想要使用网络库中的 IP 类。 ip 类不依赖于其他库。网络库中的其他功能依赖于其他外部库。如果您将网络库链接为 LIB,则只需链接 ip 类 ->您不需要其他库,因为其他代码不会被链接。当您使用DLL时,DLL中的所有代码都需要实例化->因此您需要提供其他外部库。
When you link to a LIB it adds all the symbols/functions you actually use to your executable. The ones you don't use won't get added. When you link to a dll - all the code from the external library gets loaded. If this additional code (code you don't use) depends on more external libraries you need to provide these as well.
One example: You want to use a ip class from a network library. The ip class does not depend on other libraries. Other functions in the network library depend on other external libraries. If you link the network library as a LIB you just link the ip class -> you don't need the other libraries since the other code wont get linked. When you use the DLL all code in the dll need to be instanciated -> so you will need to provide the other external libraries.
构建 DLL 更像是构建应用程序而不是库。构建应用程序和 DLL 之间的区别在于了解可能调用的内容。在应用程序中,所有未使用的符号都可以在构建中丢弃,但在 DLL 中,您不能删除未使用的符号 - 这将是所有符号......
如果您能够调用 DLL 链接的所有符号,您会在静态库中发现相同的链接问题。
Building a DLL is more like building an application than a library. The difference between building an application and a DLL is knowledge of what might be called. In an application all symbols that are not used can be discarded in the build, but in a DLL you cannot strip symbols that are not used - that would be all of them...
You would find the same link problems in your static libraries if you where able to call all the symbols that the DLL links.