c++
程式中可能包含由其他語言(例如c語言)寫出的內容。不同的語言可能在使用暫存器儲存引數的方式、引數放入堆疊的順序及編譯器傳遞給鏈結器的方面存在差異,造成程式之間的協作比較困難。例如c++
為支援過載,程式編譯後的名稱與c
語言不同,例如乙個foo
函式:
int foo(int x, int y);
在c++
語言編譯後生成的名字就是類似_foo_int_int
的名稱,而c語言編譯後就是_foo
。因此當在c++
宣告引用乙個c
程式庫的foo
函式時,在鏈結過程中,它就會從c
程式庫中去尋找_foo_int_int
函式,而實際上在c
庫中只存在_foo
函式,因此就會出現找不到指定的鏈結符號的錯誤。
extern "c" int foo(int x, int y);
說明函式將以c
鏈結約定的方式進行鏈結。 這樣在c++程式中,它就會以_foo
的名稱去從c程式庫中尋找鏈結的函式,就可以鏈結成功。
宣告為extern "c"
只是改變了鏈結方式,但不影響函式的語義,在c++
中,宣告為extern "c"
的函式仍然遵循c++
的型別檢查和引數轉換原則。
extern "c"
鏈結塊也可以包裹整個標頭檔案:
extern "c"
c++
提供了_cplusplus
巨集,可以 保證在c檔案下不包含extern "c
「鏈結約定,而在c++
程式中,包含c
鏈結約定:
#ifdef _cplusplus
extern "c"
#endif
/**************************************
* foolib.h *
* *
* 乙個簡單c程式庫的標頭檔案 *
**************************************/
int foo(int, int);
/**************************************
* foolib.c *
* *
* 乙個簡單c程式庫的定義檔案 *
**************************************/
#include
#include "foolib.h"
int foo(int x, int y)
/*****
*****
*****
*****
*****
*****
*****
*****
* foolib_caller.cpp *
* *
* 呼叫c程式庫的函式的c++程式 *
*****
*****
*****
*****
*****
*****
*****
*****/
#include
#include "foolib.h"
int main()
首先構建foolib.c
檔案構建c
程式庫libfoolib.a
,然後鏈結到c++
程式中,由於兩種模式編譯出的函式名稱不同,鏈結失敗,找不到函式定義。
現在在c++程式中新增鏈結定義,宣告foolib.h中的函式都是以c語言的模式進行鏈結的,現在可以成功鏈結。
/*****
*****
*****
*****
*****
*****
*****
*****
* foolib_caller.cpp *
* *
* 呼叫c程式庫的函式的c++程式 *
*****
*****
*****
*****
*****
*****
*****
*****/
#include
extern "c"
int main()
bjarne stroustrup著,裘宗燕譯. c++程式語言(特別版).機械工業出版社 2009. C程式的編譯鏈結過程
程式由原始檔編譯得到可執行檔案看起來好像是很簡單的過程,windows的ide環境下,點一下bulid就可以生成可執行檔案,在linux環境下,gcc編譯器也提供了很多選項可以很方便的從原始檔生成可執行檔案。事實上程式的編譯和鏈結是乙個非常複雜的過程,ide幫我們隱藏了大量的細節。下面我們以最經典的...
linux下C程式的編譯鏈結
linux下c程式的編譯可以分為四個步驟,分別是預處理,編譯,彙編和鏈結。1.預編譯 首先預處理完成預替換 去注釋 標頭檔案按照路徑展開 以及條件編譯。建立乙個test.c檔案。裡面寫入注釋 巨集定義 標頭檔案 條件編譯。如下圖 使用的gcc命令是 gcc e test.c o test.i gcc...
程式鏈結與裝載
程式的執行需要執行環境支撐,其執行環境一般由記憶體 執行庫和系統呼叫構成。其中系統呼叫部分程度上充當的是程式與核心進行互動的中介。其中首先需明白,程式與記憶體關係。記憶體是承載程式執行的介質,也是程式進行各種運算和表達的場所。window在預設情況下會將高位址的 2g 空間分配給核心 4g記憶體情況...