#ifdef __cplusplus
extern "C" {
#endif
// C 兼容聲明
#ifdef __cplusplus
}
#endif
__cplusplus 是 C++ 編譯器預定義宏。**作用:僅在 C++ 編譯單元中啟用 extern "C",C 編譯器直接忽略該塊**,避免語法錯誤。
| 語言 | 符號生成規則 | 示例 |
|---|---|---|
| C | 函數名(可能加前綴 _) | _f |
| C++ | 函數名 + 參數類型 + 返回類型 + 命名空間 + 類名 + 修飾碼 | __Z1fv (GCC) / ?f@@YAHXZ (MSVC) |
原因:C++ 支持重載、命名空間、類成員,需要唯一編碼區分同名函數。C 無此需求。
// C 庫頭文件 c_lib.h
#ifndef C_LIB_H
#define C_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
int c_add(int a, int b);
void c_init();
#ifdef __cplusplus
}
#endif
#endif
// C++ 使用
extern "C" { #include "c_lib.h" } // 或頭文件內已守護
int main() { c_init(); return c_add(1,2); }
// C++ 庫頭文件 cpp_lib.h
#ifndef CPP_LIB_H
#define CPP_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
int cpp_add(int a, int b); // 實現需在 .cpp 中同樣標註
#ifdef __cplusplus
}
#endif
#endif
// C 使用
#include "cpp_lib.h" // 無 extern "C",僅見 C 風格聲明
int main() { return cpp_add(1,2); }
#ifdef __cplusplus extern "C" { #endifextern "C" int cpp_add(...) 定義處必須標註extern "C" 函數參數/返回類型限於 POD、指針、extern "C" 函數指針,**禁用 C++ 類、引用、重載、模板、lambda**#pragma pack 显式控制extern "C" 函數**不得拋出 C++ 異常**,需內部捕獲轉錯誤碼// C 庫接口
typedef void (*Callback)(int status);
extern "C" void c_register_cb(Callback cb);
// C++ 實現回調
extern "C" void my_callback(int status) { /* C++ 邏輯 */ }
void register_from_cpp() {
c_register_cb(my_callback); // 類型匹配,鏈接符號兼容
}
extern "C" 是 C/C++ 混合編程的基石橋樑,本質是**在鏈接層統一符號規範**。掌握名稱修飾差異、編譯器守護邏輯、跨語言介面設計規範、異常/佈局邊界條件,才能構建穩健的混合工程體系。