c++ 中extern C 及#ifdef __cplusplus的作用
淺析extern “C”的作用
?
????????關于extern “C”的作用和意思,網上資料已經有很多了(我也參考了幾篇),不過我還是覺得有必要自己總結一下,畢竟“好記性不如爛筆頭”嘛~~
????????到C標準函數庫的頭文件里看看,一般會經??匆娪腥缦潞甓x(除非你從來沒有查看類似printf函數在頭文件中的定義,就另當別論了:-()
#ifdef ?__cplusplus
extern "C" {
#endif
…… (C函數聲明)
#ifdef ?__cplusplus
}
#endif
????????簡單來說,這個extern“C”用于C++代碼調用C的函數(至于C代碼如何調用C++函數,還是問問Google大神吧~)
????????先撇開上述的extern “C”,看看C函數和C++函數的匯編代碼,就知道在目標文件中,C函數名和C++函數名采用不同的命名規則。
????????VS2010新建一個Windows Console工程,添加一個.c和.cpp文件,文件里的代碼都一樣,如下
void hello()
{
?
}
????????為了使匯編文件的內容簡單一些,這里函數體是空,而且沒有引入任何頭文件。VS2010默認不輸出.asm文件,即匯編文件。在工程的配置中,讓VS2010輸出匯編文件,如下
????????編譯解決方案(或按“F7”),可以在工程目錄的Debug文件夾下,找到對應的兩個匯編文件,內容如下
????????沒有必要把這里全部的匯編代碼看懂,只要明白在源代碼中同一個hello函數,在翻譯過來的.asm文件中,hello函數名的命名不一樣就行了。
????????很明顯,如果C++代碼要調用C函數,需要按照C函數編譯后的函數名去調用這個函數。所以,extern “C”的作用就是告訴編譯器,花括號“{}”中間的這些函數聲明全部都是C函數。
????????下面修改一下.c和.cpp文件的內容,如下
// C代碼
#include <stdio.h>
?
void hello()
{
?? ?printf("Hello, world!\n");
}
// C++代碼
void hello();
?
int main(void)
{
?? ?hello();
}
????????這里要說明下,由于.c和.cpp文件在同一個工程下,所以簡單起見,沒有使用頭文件引入hello函數,這里hello函數是全局的。運行工程發現出錯如下
????????這里?hello@@YAXXZ就是上面.cpp文件中hello函數編譯后出現在對應的.asm文件中的。顯然,編譯器按照這個名稱去找目標文件(.obj文件)中的hello是找不到的,因為.c文件編譯后的.obj文件中,hello函數名被改成_hello。
????????這時,把extern “C”加到.cpp文件中,如下
extern "C" {
?? ?void hello();
};
?
int main(void)
{
?? ?hello();
}
????????果然,程序可以通過編譯運行了。到這里,基本上extern ”C”的作用都講清楚了。至于__cplusplus宏,用于判斷當前源文件是不是C++源文件,因為extern “C”這種寫法在C源文件中不允許的,如下,所以使用__cplusplus宏可以避免extern “C”被引入到C源文件中。即
(1)當前源文件是C++,則__cplusplus宏生效,extern “C”以及花括號“{}”的內容被引入C++源代碼中;
(2)當前源文件是C,則__cplusplus宏無效,extern “C”以及花括號“{}”的內容不被引入C源代碼中。
?
參考資料:
1、http://tech.163.com/06/0118/09/27O66HCC0009159Q.html
2、http://hi.baidu.com/mailrabbit/item/d53990f26265111aa7298876
3、http://blog.csdn.net/norains/article/details/1958052
4、http://luleimi.blog.163.com/blog/static/175219645201281244439794/
————————————————
原文鏈接:https://blog.csdn.net/DayDreamingBoy/article/details/8775409
總結
以上是生活随笔為你收集整理的c++ 中extern C 及#ifdef __cplusplus的作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫基地观光车攻略
- 下一篇: 青春旋律剧情介绍