嗯......从哪里开始......
在其他语言背后发生的事情在C++中更加明显。从C++获取二进制文件(比如一个可执行文件)的过程包括首先编译源代码(这里有子步骤,但编译器处理它们)以获取目标文件,然后链接器链接目标文件以生成一个二进制。
从理论上讲,您可以简单地将项目中的所有cpp文件整合在一起并“链接”(虽然没有链接),但这需要很长时间,更重要的是,在复杂可能会耗尽编译器可用内存的项目。
因此,我们将我们的项目拆分为编译单元,按照惯例,.cpp文件代表一个编译单元。编译单元是编译生成一个目标文件的项目部分。尽管编译单元是单独编译的,但其中的一些代码必须是通用的,以便每个代码中的代码段可以使用其他代码实现的功能。 .h文件通常用于此目的。事物基本上是在其中宣布的(有些是宣布的),以便每个编译单元知道当它是生成二进制文件的链接过程的一部分时会发生什么。
这也是图书馆的问题。你可以在图书馆找到两种东西,
- 已经实现的功能,以二进制文件形式发送给您,包括几乎可以运行的CPU指令(但它们必须插入正确的位置)。这个表单伴随着.h文件,让你的.cpp文件知道库中的内容。
- 第二种类型是直接在.h 文件中实现的功能。是的,这在特殊情况下是可能的。有些情况下, 执行必须(弱必须)伴随 声明(内联函数,模板类型等)。
第一种类型有两种风格:在静态库中(.lib在windows中,.a在linux中),进入可执行文件并在链接过程中成为其一部分,以及“动态库” ,这是暴露给你的二进制文件(所以它知道它),但不成为它的一部分。因此,您的可执行文件将在运行时查找该动态库(Windows中的.dll文件和Linux f.x.中的.so文件)。
因此,为了使您的.cpp文件能够从库中接收服务,他们必须使用#include
的.h文件来了解它们的内容。稍后,在链接期间,您必须显示链接器在哪里(文件系统中的哪个路径)来查找这些库的二进制组件。最后,如果库是动态的,则在运行时必须可以访问.dll(或.so's等)(例如,将它们保存在同一个文件夹中)。
在编译你的编译单元时,你必须告诉编译器在哪里找到.h文件。否则,它将看到的将是#include <something.h>
,并且它不知道在哪里找到该文件。使用gcc,您可以通过-I
选项告诉编译器。请注意,您只需告诉该文件夹。同样重要的是,如果include指令看起来像#include<somefolder/somefile.h>
,则不应在路径中包含somefolder
。所以调用的样子:
g++ mycompilationunit.cpp -IPATH/TO/THE/INCLUDED/FILES -IPATH/TO/OTHER/INCLUDED/FILES -c
的-c
选项告诉它不应该试图使一个可执行刚刚从这个编译单元的编译器,因此它创建.o文件,要与其他人晚链接。由于我们没有告诉它输出文件的名字,所以它会吐出mycompilationunit.o
。
现在我们想要生成我们的二进制文件(你可能想要一个可执行文件,但是你也可以创建一个你的库文件)。所以我们必须告诉链接器进入二进制文件的所有内容。所有的目标文件和所有的静态和动态库。所以,我们说(注:G ++这里也作为连接器)
g++ objectfile1.o objectfile2.o objectfile3.o -LPATH/TO/LIBRARY/BINARIES -llibrary1 -llibrary2 -o myexecutable
这里,-l选项的例子言自明。 -l选项指示要查找哪些二进制文件。如果链接器在路径中找到它们,它将接受静态和动态库,如果找到它们,它将选择一个。请注意,-l后面的内容不是完整的二进制名称。例如,在linux库名称中,采用liblibrary.so.0
的形式,但在链接器命令中它们被称为-llibrary。最后-o告诉编译器什么名字给你的可执行文件。你需要一些其他的选项f.x.创建一个动态库,但你现在可能不需要知道它们。
你一定要去找你的老师,建立一个项目将会涉及更多的东西,这里可以简单地回答。如果遇到特定问题,也许会出现一条奇怪的错误消息,我们可以在那里帮助。 – Collin 2012-03-22 18:37:57
你是什么意思的“处理”? – 2012-03-22 18:38:13
如果该课程不包括C++基础知识,我会推荐[一本好书](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – 2012-03-22 18:38:17