【问题标题】:C++ Libraries, Static and DynamicC++ 库,静态和动态
【发布时间】:2014-05-22 19:40:23
【问题描述】:

我正在阅读一篇关于 c++ 库和静态/动态库以及链接的文章。 我的问题如下:

1) 我们必须编译要插入到库中的文件,然后使用命令 ar -crsv 来创建库文件? (是必须以 lib 开头并以 .a 结尾的存档吗?)

2) g++的-I和-L命令用了一次?向编译器“说”库在哪里?还是每次编译使用库的源代码?

3) 必须使用#include 来包含库?如果是的话,用什么名字?

我不太明白静态库和静态链接是什么意思,动态链接是什么意思? 我所理解的是,静态库和链接是当我们将程序与库合并时,在原始位置不需要原始程序? 对于动态,我所知道的是代表动态链接库的 DDl。那么对于这个DDL我能想到的唯一区别就是加载到主存中了,但是我很困惑

任何有知识的人都可以将我的 - 可能是错误的 - 知识整理成正确的顺序并解释更多这些术语吗?

谢谢!

【问题讨论】:

  • 您指的是 g++ 并已将问题标记为“dll”。你在 Windows 中使用 g++ 吗?这都是非常特定于工具链的。
  • 不,我在Linux上,但是文章中有一点动态链接是DDL的快捷方式。

标签: c++ dll shared-libraries static-libraries


【解决方案1】:

假设您的代码是一个名为 main.cpp 的文件,如下所示:

#include<headerFromSomeLibrary>
#include<headerFromSomeOtherLibrary>

int main()
{
    int var = functionFromTheLibrary();
    int otherVar = functionFromTheOtherLibrary();

    return var + otherVar;
}

编译将分两步进行。

首先,你将把 main.cpp 编译成一个目标文件,使用如下命令:

g++ -o main.o -c main.cpp -IheaderDirectory

其中 main.o 是要生成的目标文件的名称,headerDirectory 是包含 中包含的头文件的目录的路径main.cpp.

为了能够检查您的语法是否正确,编译器需要知道在 main.cpp 中调用但未在此处定义的类和函数的外观(在此情况下,它们来自库,但如果它们是由您在另一个文件中定义的,则它们的工作方式相同)。

这就是#include 指令的用武之地:它们指向包含被调用函数声明的头文件,并允许编译器完成其工作。如果声明位于名为 headerFromSomeLibrary.h 的头文件中,则相应的指令将是:

#include<headerFromeSomeLibrary>

此时,生成的文件 (main.o) 包含 main.cpp 中定义的函数的低级版本(在这种情况下只有 main() )。它还包含许多符号,允许识别在 main.cpp 中定义并由 main.cpp 调用的函数。


第二步是链接步骤。链接命令将如下所示:

g++ -o myProgram main.o -LsomeDirectory -lsomelibrary -lsomeotherlibrary

其中 myProgram 是您要赋予可执行文件的名称,headerDirectory 是包含头文件的目录的路径,someDirectory是包含 libsomeLibrary.alibsomeOtherLibrary.a(您正在使用的库的二进制文件)的目录的路径。

main.o类似,libsomelibrary.alibsomeotherlibrary.a包含函数的定义(即在main()),以及标识它们的符号。链接步骤的作用是使用符号将函数定义连接到函数调用。

如果库中的函数在文件 myfunctions.h 中声明并在 myfunctions.cpp 中定义,编译指令将如下所示:

g++ -o main.o -c main.cpp
g++ -o myfunctions.o -c myfunctions.cpp
g++ -o myProgram main.o myfunctions.o

基本上,-I 选项用于告诉编译器缺少的头文件在哪里,-l 选项用于告诉它缺少的二进制文件的名称,-L 选项用于告诉它在哪里可以找到这些二进制文件。这些选项不会“停留”从一次调用 g++ 到下一次调用(这没有意义)。


现在,您询问了静态链接和动态链接之间的区别。我上面解释的实际上是静态(即编译时)链接。在静态链接的情况下,编译器将在库中获取它需要的函数定义,并将它们添加到最终的可执行文件中。这很好,因为您的可执行文件不需要其他任何东西来工作,而且您的编译器将能够在获取函数后进行优化。

但是,这并不总是您想要做的。一些库被许多不同的程序使用,您可以通过在程序之间共享库来节省大量空间。这就是动态(即运行时)链接的情况。在这种情况下,程序会在需要时简单地获取库。

【讨论】:

  • 非常棒!谢谢你,我明天再检查你的解释,然后再检查接受按钮。
猜你喜欢
  • 2011-08-28
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多