简体   繁体   English

为什么 C++ 链接器在构建过程中需要库文件,即使我是动态链接的?

[英]Why does the C++ linker require the library files during a build, even though I am dynamically linking?

I have a C++ executable and I'm dynamically linking against several libraries (Boost, Xerces-c and custom libs).我有一个 C++ 可执行文件,并且我正在动态链接多个库(Boost、Xerces-c 和自定义库)。

I understand why I would require the .lib/.a files if I choose to statically link against these libraries ( relevant SO question here ).我明白为什么我需要 .lib/.a 文件,如果我选择静态链接这些库( 相关的 SO 问题在这里)。 However, why do I need to provide the corresponding .lib/.so library files when linking my executable if I'm dynamically linking against these external libraries?但是,如果我动态链接到这些外部库,为什么在链接我的可执行文件时需要提供相应的 .lib/.so 库文件?

The compiler isn't aware of dynamic linking, it just knows that a function exists via its prototype.编译器不知道动态链接,它只知道函数通过其原型存在。 The linker needs the lib files to resolve the symbol.链接器需要 lib 文件来解析符号。 The lib for a DLL contains additional information like what DLL the functions live in and how they are exported (by name, by ordinal, etc.) The lib files for DLL's contain much less information than lib files that contain the full object code - libcmmt.lib on my system is 19.2 MB, but msvcrt.lib is "only" 2.6 MB. DLL 的 lib 包含附加信息,例如函数所在的 DLL 以及它们如何导出(按名称、按序数等)。 DLL 的 lib 文件比包含完整目标代码的 lib 文件包含的信息少得多 - libcmmt我系统上的 .lib 是 19.2 MB,但 msvcrt.lib 是“仅”2.6 MB。

Note that this compile/link model is nearly 40 years old at this point, and predates dynamic linking on most platforms.请注意,此编译/链接模型此时已有近 40 年的历史,并且早于大多数平台上的动态链接。 If it were designed today, dynamic linking would be a first class citizen (for instance, in .NET, each assembly has rich metadata describing exactly what it exports, so you don't need separate headers and libs.)如果它是今天设计的,动态链接将是一等公民(例如,在 .NET 中,每个程序集都有丰富的元数据来准确描述它导出的内容,因此您不需要单独的头文件和库。)

Raymond Chen wrote a couple blog entries about this specific to Windows. Raymond Chen 写了几篇关于此特定于 Windows 的博客条目。 Start with The classical model for linking and then follow-up withWhy do we have import libraries anyway?链接的经典模型开始,然后跟进为什么我们仍然有导入库? . .

To summarize, history has defined the compiler as the component that knows about detailed type information, whereas the linker only knows about symbol names.总而言之,历史将编译器定义为知道详细类型信息的组件,而链接器只知道符号名称。 So the linker ends up creating the .DLL without type information, and therefore programs that want to link with it need some sort of metadata to tell it about how the functions are exported and what parameter types they take and return.所以链接器最终创建了没有类型信息的 .DLL,因此想要链接它的程序需要某种元数据来告诉它函数是如何导出的,以及它们采用和返回的参数类型。

The reason .DLLs don't have all the information you need to link with them directly is is historic, and not a technical limitation. .DLL 没有您需要直接链接到它们的所有信息的原因是历史性的,而不是技术限制。

For one thing, the linker inserts the versions of the libraries that exist at link time so that you have some chance of your program working if library versions are updated.一方面,链接器会插入链接时存在的库版本,这样如果库版本更新,您的程序就有机会运行。 Multiple versions of shared libraries can exist on a system.一个系统上可以存在多个版本的共享库。

The linker has the job of validating that all your undefined symbols are accounted for, either with static content or dynamic content.链接器的任务是验证所有未定义的符号是否都被考虑在内,无论是静态内容还是动态内容。

By default, then, it insists on all your symbols being present.默认情况下,它坚持所有符号都存在。

However, that's just the default.但是,这只是默认设置。 See -z, and --allow-shlib-undefined, and friends.请参阅 -z 和 --allow-shlib-undefined 以及朋友。

Perhaps this dynamic linking is done via import libraries (function has __declspec(dllimport) before definition).也许这个动态链接是通过导入库完成的(函数在定义之前有 __declspec(dllimport))。
If this is the way than compilator expects that there's __imp_symbol function declared and this function is responsible for forwarding call to the right library dynamically loaded.如果这是编译器预期的方式,则声明了 __imp_symbol 函数,该函数负责将调用转发到动态加载的正确库。
Those functions are generated during linkage of symbols with __declspec(dllimport) keyword这些函数是在符号与 __declspec(dllimport) 关键字链接期间生成的

Here is a very SIMPLIFIED description that may help.这是一个非常简单的描述,可能会有所帮助。 Static linking puts all of the code needed to run your program into the executable so everything is found.静态链接将运行程序所需的所有代码放入可执行文件中,以便找到所有内容。 Dynamic linking means some of the required code does not get put into the executable and will be found at runtime.动态链接意味着某些必需的代码不会放入可执行文件中,而是会在运行时找到。 Where do I find it?我在哪里可以找到它? Is function x() there?有函数 x() 吗? How do I make a call to function x()?如何调用函数 x()? That is what the library tells the linker when you are dynamically linking.这就是库在动态链接时告诉链接器的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使两个文件都在同一目录中,为什么也会出现链接器错误? - Why am I getting a linker error even though both files are in the same directory? 为什么在C ++ AMP项目的构建过程中出现链接器错误 - Why do I get linker errors during build of C++ AMP project 为什么复制构造函数被调用,即使我实际上是在C ++中复制到已经创建的对象? - why copy constructor is getting called even though I am actually copying to already created object in C++? 为什么Visual Studio C ++甚至在不需要的文件上也要求包含“ StdAfx.h”? - Why does Visual Studio C++ require including “StdAfx.h” even on files that don't need it? 在不需要 class 实例化的 C++ 中构建一个库 - Build a library in C++ which does not require class instantiation 哪个C ++单元测试框架不需要我将应用程序构建为库? - Which C++ Unit Test framework does not require I build my application as a library? 即使我将变量留空,C++ 也会初始化变量的值,为什么会发生这种情况? - C++ initializes value for variable even though I left it empty, why does this happen? 为什么我的C ++链接器仅在删除boost共享对象文件后才能工作? - Why does my C++ linker only work after I delete boost shared object files? 尝试从使用makefile创建的目标文件进行构建时,C ++链接器错误。 当我刚刚构建它时不会发生 - C++ linker error when trying to build from object files made using makefile. Does not occur when I just build it C ++ Builder链接器是否支持功能级别的链接? - Does C++ Builder linker support function-level linking?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM