在cpp的**之中有這樣的一段**:
#ifdef __cplusplus
extern "c"
#endif
解釋一下:
首先,__cplusplus是cpp中的自定義巨集,那麼定義了這個巨集的話表示這是一段cpp的**,也就是說,上面的**的含義是:如果這是一段cpp的**,那麼加入extern "c"處理其中的**。
要明白為何使用extern "c",還得從cpp中對函式的過載處理開始說起。在c++中,為了支援過載機制,在編譯生成的彙編碼中,要對函式的名字進行一些處理,加入比如函式的返回型別等等.而在c中,只是簡單的函式名字而已,不會加入其他的資訊.也就是說:c++和c對產生的函式名字的處理是不一樣的.
比如下面的一段簡單的函式,我們看看加入和不加入extern "c"產生的彙編**都有哪些區別:
int f(void)
在加入extern "c"的時候產生的彙編**是:
.file "test.cpp"
.text
.align 2
.globl _f
.def _f; .scl 2; .type 32; .endef
_f:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
但是在不加入了extern "c"如下:
.file "test.cpp"
.text
.align 2
.globl __z1fv
.def __z1fv; .scl 2; .type 32; .endef
__z1fv:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
兩段彙編**同樣都是使用gcc -s命令產生的,所有的地方都是一樣的,唯獨是產生的函式名,乙個是_f,乙個是__z1fv。
明白了加入與不加入extern "c"之後對函式名稱產生的影響,我們繼續討論:為什麼需要使用extern "c"呢?c++之父在設計c++之時,考慮到當時已經存在了大量的c**,為了支援原來的c**和已經寫好c庫,需要在c++中盡可能的支援c,而extern "c"就是其中的乙個策略。
試想這樣的情況:乙個庫檔案已經用c寫好了而且執行得很良好,這個時候我們需要使用這個庫檔案,但是我們需要使用c++來寫這個新的**。如果這個**使用的是c++的方式鏈結這個c庫檔案的話,那麼就會出現鏈結錯誤.我們來看一段**:首先,我們使用c的處理方式來寫乙個函式,也就是說假設這個函式當時是用c寫成的:
extern "c"
}
編譯命令是:gcc -c f1.c -o f1.o 產生了乙個叫f1.o的庫檔案。再寫一段**呼叫這個f1函式:
// test.cpp
//這個extern表示f1函式在別的地方定義,這樣可以通過
//編譯,但是鏈結的時候還是需要
//鏈結上原來的庫檔案.
extern void f1();
int main()
通過gcc -c test.cpp -o test.o 產生乙個叫test.o的檔案。然後,我們使用gcc test.o f1.o來鏈結兩個檔案,可是出錯了,錯誤的提示是:
test.o(.text + 0x1f):test.cpp: undefine reference to 'f1()'
也就是說,在編譯test.cpp的時候編譯器是使用c++的方式來處理f1()函式的,但是實際上鏈結的庫檔案卻是用c的方式來處理函式的,所以就會出現鏈結過不去的錯誤:因為鏈結器找不到函式。
因此,為了在c++**中呼叫用c寫成的庫檔案,就需要用extern "c"來告訴編譯器:這是乙個用c寫成的庫檔案,請用c的方式來鏈結它們。
比如,現在我們有了乙個c庫檔案,它的標頭檔案是f.h,產生的lib檔案是f.lib,那麼我們如果要在c++中使用這個庫檔案,我們需要這樣寫:
extern "c"
回到上面的問題,如果要改正鏈結錯誤,我們需要這樣子改寫test.cpp:
extern "c"
int main()
重新編譯並且鏈結就可以過去了.
總結:
1、c和c++對函式的處理方式是不同的.extern "c"是使c++能夠呼叫c寫作的庫檔案的乙個手段,如果要對編譯器提示使用c的方式來處理函式的話,那麼就要使用extern "c"來說明。
2、被extern "c"修飾的變數和函式是按照c語言方式編譯和連線的。
C 之 extern C的作用詳解
extern c 的主要作用就是為了能夠正確實現c 呼叫其他c語言 加上extern c 後,會指示編譯器這部分 按c語言的進行編譯,而不是c 的。由於c 支援函式過載,因此編譯器編譯函式的過程中會將函式的引數型別也加到編譯後的 中,而不僅僅是函式名 而c語言並不支援函式過載,因此編譯c語言 的函式...
探索C 詳解extern C
ifdef cplusplus extern c endif 這樣的 到底是什麼意思呢?首先,cplusplus是cpp中的自定義巨集,那麼定義了這個巨集的話表示這是一段cpp的 也就是說,上面的 的含義是 如果這是一段cpp的 那麼加入extern c 處理其中的 要明白為何使用extern c ...
探索C 的秘密之詳解extern 「C」
時常在cpp的 之中看到這樣的 ifdef cplusplus extern c endif 這樣的 到底是什麼意思呢?首先,cplusplus是cpp中的自定義巨集,那麼定義了這個巨集的話表示這是一段cpp的 也就是說,上面的 的含義是 如果這是一段cpp的 那麼加入extern c 處理其中的 ...