导入库如何工作?细节?

时间:2010-08-26 08:48:10

标签: c++ c windows visual-c++

我知道这对极客来说似乎很基本。但我想说清楚。

当我想使用Win32 DLL时,通常我只需要调用像LoadLibrary()和GetProcAdderss()这样的API。但最近,我正在使用DirectX9进行开发,我需要添加 d3d9.lib d3dx9.lib 等文件。

我听说LIB用于静态链接,DLL用于动态链接。

所以我目前的理解是LIB包含方法的实现,并在链接时静态链接作为最终EXE文件的一部分。虽然DLL在运行时是动态加载的,但不是最终EXE文件的一部分。

但有时候,有一些LIB文件附带 DLL文件,所以:

  • 这些LIB文件是什么?
  • 他们如何实现他们的意图?
  • 是否有任何工具可以让我检查这些LIB文件的内部结构?

更新1

检查维基百科后,我记得这些LIB文件名为import library。 但我想知道它如何与我的主应用程序和动态加载的DLL一起工作。

更新2

正如RBerteig所说,LIB文件中存在一些与DLL一起出现的存根代码。所以调用序列应该是这样的:

我的主要应用 - > LIB中的存根 - >真正的目标DLL

那么这些LIB中应包含哪些信息?我能想到以下几点:

  • LIB文件应包含相应DLL的完整路径;因此DLL可以由运行时加载。
  • 每个DLL导出方法的入口点的相对地址(或文件偏移量?)应该在存根中编码;因此可以进行正确的跳转/方法调用。

我是对的吗?还有什么吗?

BTW:有没有可以检查导入库的工具?如果我能看到它,就不会再有疑惑了。

4 个答案:

答案 0 :(得分:85)

答案 1 :(得分:3)

这些.LIB导入库文件在以下项目属性Linker->Input->Additional Dependencies中用于构建一堆dll,这些dll在链接时需要附加信息,这些信息由导入库.LIB文件提供。在下面的示例中,为了不获取链接器错误,我需要通过它们的lib文件引用dll的A,B,C和D. (请注意,链接器要查找这些文件,您可能需要在Linker->General->Additional Library Directories中包含它们的部署路径,否则您将收到有关无法找到任何提供的lib文件的构建错误。)

Linker->Input->Additional Dependencies

如果您的解决方案正在构建所有动态库,那么您可以通过依赖Common Properties->Framework and References对话框下公开的引用标志来避免此显式依赖项规范。这些标志似乎使用* .lib文件代表您自动执行链接。 Framework and References

然而,这就是它所说的 Common 属性,它不是配置或平台特定的。如果您需要像我们的应用程序一样支持混合构建场景,我们有一个构建配置来呈现静态构建和一个特殊配置,该构造构建了部署为动态库的程序集子集的约束构建。在各种情况下,我使用Use Library Dependency InputsLink Library Dependencies标志设置为true来构建事物并稍后实现简化,但是当我将代码引入静态构建时,我引入了大量的链接器警告和对于静态构建,构建速度非常慢。我最后介绍了一堆这样的警告......

warning LNK4006: "bool __cdecl XXX::YYY() already defined in CoreLibrary.lib(JSource.obj); second definition ignored  D.lib(JSource.obj)

我最后使用Additional Dependencies的手动规范来满足动态构建的链接器,同时通过不使用减慢它们的公共属性来保持静态构建器的快乐。当我部署动态子集构建时,我只部署dll文件,因为这些lib文件仅在链接时使用,而不是在运行时使用。

答案 2 :(得分:2)

有三种库:静态库,共享库和动态加载库。

静态库在链接阶段与代码链接,因此它们实际上位于可执行文件中,与共享库不同,共享库只有在共享库文件中查找的存根(符号),在运行时加载主函数被调用之前的时间。

动态加载的文件很像共享库,除非它们在您编写的代码需要时加载。

答案 3 :(得分:0)