嗯......從哪裏開始......
在其他語言背後發生的事情在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