在C++编译器下,将代码按照C语言编译
extern "C"的使用
- 一、定義-defintion
- 二、extern "C"使用舉例-example
- 三、extern "C"的用武之處在哪?
- 四、extern "C"常用特性
- 1.C++調用第三方庫(含.h&.c文件)
- 2. C語言也調用第三方庫(含.h&.c文件)
- a. #define __cplusplus解釋
- b. #ifdef條件編譯
- c. 啟示
- 五、不相關學習tips
- 1.防止某個.h文件被重復include
- 2.防止某個.h文件被重復include(#pragma)
一、定義-defintion
被extern "C"修飾的代碼會按照C語言的方式去編譯
二、extern "C"使用舉例-example
我們都知道,C語言不支持函數重載,只有C++才支持函數重載。下方兩個函數就會按照C語言進行編譯,由于是重載函數,所以會報錯
extern "C" void function(int v1, double v2) {cout << "int v1, double v2" << endl; } extern "C" void function(double v1, int v2) {cout << "double v1, int v2" << endl; }int main(int argc, char **argv) {function(10,10.0);//會報錯,因為C語言不支持函數重載getchar();return 0; }三、extern "C"的用武之處在哪?
- 由于C、C++編譯方式的不同,這種機制往往用在C\C++混合開發,往往做項目時,可能會用到第三方庫:這個庫可能是C語言寫的,這時候這種機制就很重要。
- 我還是想要用第三方庫里的函數,怎么辦呢?這時候就要借助extern “C”
四、extern "C"常用特性
1.C++調用第三方庫(含.h&.c文件)
函數如果同時有聲明(.h文件)和實現(.c),extern “C"修飾只放在函數聲明中,即.c文件實現函數時,可以不用再次修飾。如果.cpp文件引用.h中的C語言函數時:如果.h的函數已經被extern “C"修飾,則直接#include””;如果沒有被修飾,則必須extern “C” #include""
- .h頭文件中的函數聲明沒有被extern "C"修飾
- .h頭文件中的函數聲明有被extern "C"修飾
有函數聲明和實現時,想要某個函數采用C語言編譯,最好只在函數聲明前采用extern “C” 修飾,在函數實現前不做任何操作
2. C語言也調用第三方庫(含.h&.c文件)
由于整個項目C++需要調用第三方庫(第三方庫是用C語言寫的),所以用extern “C” 修飾一下這個第三方庫里的函數,即可被C++調用。但,我這個項目里如果有.c文件也需要調用這個第三方庫,可以直接調用嗎?答案是不能的,因為這個第三方庫函數已經被extern “C” 修飾了,而C語言是不認識extern “C” 的。
我希望這個第三方庫更加的靈活,即C++調用函數時自動加上extern “C” 修飾;C語言調用,extern “C” 自動去掉
a. #define __cplusplus解釋
#define __cplusplus這個宏被默認的編寫在C++文件的最開頭,用來確認這個文件是cpp文件。只要你是cpp文件,第一行編譯器默認給你寫了一句#define __cplusplus。
b. #ifdef條件編譯
#ifdef 和 #endif // 組合使用,達到條件編譯的目的。下方代碼的最終結果就是:如果某個cpp文件調用這段代碼,才會編譯代碼段,c文件調用這段代碼,不會編譯這段代碼段,即只讀到了一對注釋
#ifdef __cplusplus //被編譯的代碼段,如果定義了名為__cplusplus的宏,這段代碼段才會被編譯,否則會被編譯器視為注釋 #endif // __cplusplus- 于是第三方庫的完美寫法是這樣的:
c. 啟示
以后凡是用C語言編寫的第三方庫,最好都要按照下述代碼改動.h文件。這樣的話,C++和C語言文件都可以調用這個第三方庫,不僅不會出錯,還會使得代碼更加規范
//第三方C語言庫 #ifdef __cplusplus extern "C" { #endif // __cplusplusvoid function1(); void function2(); void function3(); void function4(); void function5(); ..... #ifdef __cplusplus } #endif // __cplusplus五、不相關學習tips
1.防止某個.h文件被重復include
我們在開發的時候,當代碼量很大時,我們可能會在中間include頭文件,下面的組合會解決這個問題
#ifndef BBB
#define BBB
…BBB.h頭文件代碼
#endif //!BBB
- 錯誤示例
- 正確且規范的編寫.h頭文件。
#include<BBB.h>就相當于把BBB.h文件中的代碼全部拷貝一份
某個.cpp文件 #include<BBB.h> //#ifndef BBB //如果沒有定義BBB這個宏 //#define BBB //定義BBB這個宏,然后下面代碼參與編譯代碼//#endif //!BBB ... 可能有很多行代碼,然后我忘了前面已經#include<BBB.h>了,我又包含了一遍 ...#include<BBB.h>//我在某處又引入了這個頭文件,這時候就會報錯,因為我重復包含了.h文件 //#ifndef BBB //如果沒有定義BBB這個宏,直接判斷失敗,因為上面已經#define BBB了一次,所以在#endif //!BBB之前的代碼都不會編譯了 //#define BBB //定義BBB這個宏,然后下面代碼參與編譯代碼//#endif //!BBB ...2.防止某個.h文件被重復include(#pragma)
新建.h頭文件時第一行出現的 #pragma once,是為了防止這個.h文件被重復包含,即也是防止cpp文件中多次包含相同的.h文件。#pragma once可以起到和上述相同的作用
#pragma once 會被定義在.h文件的開頭,也會起到防止被重復include的錯誤。但與上面的#ifndef的區別是什么呢?
#pragma once 和 #ifndef + #define + #endif //! 的區別在于,后者什么編譯器都支持,而前者則必須保證GCC3.4版本之后的編譯器才支持。同時前者只能針對整個頭文件,而后者可以針對文件中的部分代碼。
總結
以上是生活随笔為你收集整理的在C++编译器下,将代码按照C语言编译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cisco IP电话软件的WINRTP
- 下一篇: 无锡合全药业有限公司新药制剂开发服务及制