我擦 遇到個大坑啊 C和C++混合編譯問題

技術從未如此性感發表於2018-06-21

在C語言中,編譯器對於函式 int test()和int test(int a)的編譯結果得到的函式名是一樣的,所以C語言不能過載

而在C++中int test()和int test(int a)編譯後生成不同名字的函式,所以支援過載

 

1.這就產生了問題,如果在C++中呼叫C語言的int test(int a)函式,會連線錯誤,因為編譯後找不到對應名稱的函式(c和cpp生成的函式名不同)

所以需要在CPP檔案中如果要使用int test(int a)函式,需要在(include下面)用extern "C" int test(int a)

如果呼叫的C函式特別多,也可以用下面的方式宣告

extern "C"

{

需要呼叫的c語言函式

int test(int a);

}

 

或者

extern "C"

{

 #include "XXX.h"

這樣會把XXX.h裡面宣告的函式都變成C函式生成規則

}

 

 

2.如果要在.c檔案中需要呼叫CPP函式需要在.cpp檔案中用extern "C"{

cpp函式的實現

}

然後系統在編譯這個函式的時候就會自動按照C語言的規則進行編譯

 

3.如果要寫一套函式庫,同時提供給C和CPP使用,那必須用C語言規則進行編譯

如果是寫在CPP檔案中的,必須要加extern "C"宣告

--1.在cpp檔案中加上extern,讓函式編譯是用c規則編譯

--2.在呼叫者的cpp檔案中用extern "C"{include 引入標頭檔案}

 

4.但是3的實現比較麻煩,只要呼叫通用函式就得在呼叫者的cpp檔案中用extern引入標頭檔案

解決方法:在通用函式的.h和.cpp檔案中,都用extern來宣告--(但是此時就會讓c呼叫不了通用函式,因為c裡面沒有extern,c包含的標頭檔案包含extern,所以編譯通不過)

所以要在通用函式的.h檔案裡面用

#ifdef __cplusplus

extern "C" {

#endif

int sum(int, int);

#ifdef __cplusplus

}

#endif

 

因為cpp在編譯時會自動生成__cplusplus這個巨集,所以利用這一點,可以實現c檔案中不包含extern

cpp中包含extern

 

 

相關文章