extern C 的解釋和使用方法

2021-05-27 10:03:44 字數 2294 閱讀 3677

#ifdef __cplusplus 

extern "c" 處理其中的**。 

要明白為何使用extern "c",還得從cpp中對函式的過載處理開始說起。在c++中,為了支援過載機制,在編譯生成的彙編碼中,要對函式的名字進行一些處理,加入比如函式的返回型別等等.而在c中,只是簡單的函式名字而已,不會加入其他的資訊.也就是說:c++和c對產生的函式名字的處理是不一樣的. 

比如下面的一段簡單的函式,我們看看加入和不加入extern "c"產生的彙編**都有哪些變化: 

int f(void) 

return 1; 

在加入extern"c"的時候產生的彙編**是: 

.file "test.cxx" 

.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.cxx" 

.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" 

void f1() 

return; 

編譯命令是:gcc -c f1.c -o f1.o 產生了乙個叫f1.o的庫檔案。再寫一段**呼叫這個f1函式: 

// test.cxx 

//這個extern表示f1函式在別的地方定義,這樣可以通過 

//編譯,但是鏈結的時候還是需要 

//鏈結上原來的庫檔案. 

extern void f1(); 

int main() 

f1(); 

return 0; 

通過gcc-c test.cxx -o test.o 產生乙個叫test.o的檔案。然後,我們使用gcctest.o f1.o來鏈結兩個檔案,可是出錯了,錯誤的提示是: 

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++中使用這個庫檔案,我們需要這樣寫: 

extern "c" 

#include "f.h" 

回到上面的問題,如果要改正鏈結錯誤,我們需要這樣子改寫test.cxx: 

extern "c" 

extern void f1(); 

int main() 

f1(); 

return 0; 

重新編譯並且鏈結就可以過去了. 

總結 

c和c++對函式的處理方式是不同的.extern"c"是使c++能夠呼叫c寫作的庫檔案的乙個手段,如果要對編譯器提示使用c的方式來處理函式的話,那麼就要使用extern"c"來說明. 

Qt訊號和槽解釋與使用方法

qt訊號和槽的理解 訊號和槽機制是qt的核心特徵。訊號和槽的特點 1 乙個訊號可以關聯乙個槽,或者多個槽。多個訊號也可以關聯乙個槽。如果存在多個槽與某個訊號相關聯,那麼當這個訊號被發射時,槽的執行順序與關聯順序相同。2 乙個類的訊號可以關聯到其他類的槽。使用方法 對於訊號和槽,需要使用signal和...

extern C和 cplusplus的使用

1.c語言檔案中有如下形式 ifdef cplusplus extern c endif2.理解 這種形式的宣告表明如果該檔案被c 程式呼叫,使用c語言的語法形式編譯。如果是c 程式,c 的編譯器如g 定義了巨集 cplusplus,此時使用extern c 告訴c 編譯器下面的函式宣告等使用c語言...

解釋throw表示式和try塊的使用方法的程式

throw表示式是用在try塊中的。它用於丟擲錯誤資訊。throw丟擲的錯誤資訊被下面的catch函式接受,並且通過runtime error類的成員函式what 返回throw關鍵字丟擲的錯誤資訊。下面是源程式。sales item.h ifndef sales item define sales...