静态库&动态库:混乱

时间:2010-02-11 18:43:40

标签: linker shared-libraries static-libraries

我在这方面几乎无需澄清。我觉得术语Static library& Dynamic Library不正确。

  • lib1.o + lib2.o + lib3.o - > “LinkerOutputFile”(可执行文件或库)。
  • 如果这个“LinkerOutputFile”包含所有文件lib1.o,lib2.o,lib3.o的代码,那么它表示“LinkerOutputFile”是静态链接的“LinkerOutputFile”(可执行文件或库)。 (或)

  • 如果“LinkerOutputFile”只包含引用&其他信息关于到lib1.o,lib2.o,lib3.o,但不包含这些lib * .o文件的代码。然后它说“LinkerOutputFile”动态链接。

这如何使lib * .o文件成为静态库或动态库?它们只是库文件。

或者就是说,“LinkerOutputFile”是一个库而不是可执行文件,这取决于它是静态链接还是动态链接它的静态库或动态库。对错吗?

我知道我错了,因为,我知道

  

在大多数unix风格的平台上   扩展名

     
      
  • .a 用于静态库(存档)和
  •   
  • .so 用于共享库。
  •   
     

在Windows上:

     
      
  • .dll 表示共享库
  •   
  • .lib 表示静态或导入库。
  •   

但无法弄清楚我错在哪里。另请告诉我Static library& Dynamic Library内部不同。

此外,这是来自ABI规范:

  

本章介绍目标文件   格式,称为ELF(可执行文件和   链接格式)。主要有三个   对象文件的类型。

     

可重定位文件包含代码和数据   适合与其他物体连接   用于创建可执行文件的文件   共享对象文件。

     

可执行文件包含程序   适合执行;文件   指定exec(BA_OS)如何创建   程序的过程映像。

     

共享对象文件包含代码和   适合连接的数据   上下文。首先,链接编辑器[见   ld(BA_OS)]处理共享对象   文件与其他可重定位和共享   目标文件来创建另一个对象   文件。第二,动态链接器   将它与可执行文件相结合   和其他共享对象来创建   过程形象。

“共享对象文件”是用于说动态库(具有* .so扩展名)的其他词。但是“静态库”怎么样?这甚至没有提到它。

“Relocatable”和&之间有什么区别吗? “静态图书馆”& “导入图书馆”?请用内部结构澄清我。

3 个答案:

答案 0 :(得分:10)

.o个文件不是任何类型的库文件。它们是对象文件。

.a / .lib个文件在构建时链接。事后他们不能被替换。这使它们成为静态的。

.so / .dll文件在运行时链接。它们可以在执行开始之前随时更换。这使它们变得动态。

重定位是指在内存中放置二进制文件;静态库中的代码与二进制文件集成在一起,因此无法独立重定位。

答案 1 :(得分:4)

静态库包含复制到可执行文件中的代码。将删除程序中未引用的库中的代码。只有静态库的程序在运行时没有任何依赖项。

动态库在运行时链接 - 具有动态库引用的程序将在启动时(或按需)加载并链接库。

可重定位库是动态库的另一个词。当您与动态库链接时,将根据库在内存中的加载位置计算其中包含的函数的地址。它们是“可重定位的”,因为包含的函数的地址不是在链接时确定的。 (在静态库中,地址是在链接时计算的。)

目标文件(.o)包含已编译的代码,但不包含所有函数的最终地址。链接是链接器遍历所有目标文件并为每个被调用函数计算正确地址的过程。

答案 2 :(得分:0)

假设我的应用 StaticLib.lib 相关联,然后是应用 StaticLib的所有代码.lib 将在同一个可执行文件中。这意味着 StaticLib.h 包含函数实现。

现在,如果我将应用 DynamicLib.lib 相关联,那么我的应用将使用 DynamicLib.dll中实现的功能表示 DynamicLib.lib 包含引用,例如:

  • OpenWAV位于 DynamicLib.dll
  • 中的偏移量1处
  • DynamicLib.dll 中的偏移2处找到CloseWAV 等

名称dynamic意味着它可以由任何App加载,而不是通过与DynamicLib.lib链接,而是调用LoadLibrary()并手动导入DLL导出的函数。

关于Relocatable,此刻我对这个词并不熟悉。

我说的是Windows程序员,所以我不知道Linux上的实际情况,但从名称SO(共享对象)判断与DLL类似。

希望我的回答很有帮助!