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