1. 程式人生 > >C語言呼叫C++中的函式,extern "C"的含義

C語言呼叫C++中的函式,extern "C"的含義

C++編譯器在將cpp檔案編譯成庫時,匯出的函式名會改變,成員函式會通過加一些元素變成全域性函式,如果這時候我們需要用C語言呼叫C++的函式, 就有了一個問題,那就是不知道C++庫中匯出的函式名,這是由編譯器決定的,這個時候就需要用到extern關鍵字。例子:

test.cpp: int add(int a, int b) {     return a+b;     }

編譯: g++ -o test.o -c test.cpp nm -s test.o 檢視test.o的符號表,可以發現,並沒有add函式,而是有一個_Z3addii的函式名,這就是C++編譯器編譯之後的函式名,如果我們需要呼叫此函式,那麼 就需要使用這個函式名。

main.c: #include<stdio.h> int main() {     int i = _Z3addii(1,2);     printf("i=%d\n",i);     return 0; }

編譯連結: gcc -o main.o -c main.c gcc -o main main.o test.o ./main 可以看到輸出為: i=3 說明呼叫成功

但是使用這種方法來呼叫C++函式顯然是不可行的,這個時候就需要extern關鍵字了,修改test.cpp如下: test.cpp: extern "C" {     int add(int a, int b); }

int add(int a, int b) {     return a+b; } 編譯: g++ -o test.o -c test.cpp nm -s test.o 此時檢視test.o的符號表就有add函數了,這時就可以通過add直接來呼叫該函數了,extern "C"的含義就是告訴編譯器,下面的函式使用C風格來編譯, C語言編譯時就不會修改函式名,因為沒有過載,類,名稱空間等這些概念,函式名是唯一的,而C++因為有類、名稱空間、函式過載這些概念,所以函式名 可能是相同的,所以C++編譯器會修改函式名,使得兩個相同函式名的函式在呼叫時不會產生衝突。比如有兩個類test1和test2,它們都有同名函式add, 這時C++編譯器就會將test1中的add編譯成類似xxtest1xaddxx這樣的函式名,test2中的add會被編譯成類似xxtest2xxaddxx的函式名,這樣呼叫函式就不會衝突了。