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