C++ 库,静态和动态

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

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

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

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

3) 必须使用#include<> 包含 Libray?如果是,名字是什么?

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

任何有知识的人都可以将我的 - 可能是错误的 - 知识按正确顺序排列并解释更多这些条款吗?

谢谢!

最佳答案

假设您的代码是一个名为 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 指令的用武之地:它们指向包含所调用函数声明的 header ,并允许编译器执行其工作。如果声明位于名为 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 包含函数的定义(即那些在 < em>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 选项用于告诉编译器缺少的 header 在哪里,-l 选项告诉它缺少的二进制文件的名称,-L 选项告诉它在哪里可以找到这些二进制文件。这些选项不会从一次 g++ 调用到下一次调用“停留”(这没有意义)。


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

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

关于C++ 库,静态和动态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23815769/

相关文章:

c# - 是否可以在不是为 silverlight 构建的 silverlight 项目中包含外部 dll?

c - 需要 MSVCR120.DLL

c++ - 使用 g++ 编译动态共享库

c++ - 使用 if(char == '\n' ) 重置变量 C++

c++ - 在 vector vector 中搜索时检查 std::find 是否失败

c++ - 64 位整数方程的意外结果

c++ - 无法构建 RcppArmadillo.package.skeleton 测试包 : Multiple definition of `R_init_<name>'

c# - 为什么我无法使用Mysql数据库?

shared-libraries - 可执行文件的多个实例(使用静态库构建)是否会共享 RAM 上的任何内容

linux - arm-linux-gnueabihf-g++ arm-linux-gnueabihf/bin/ld.exe : cannot find -llibxxx