extern “C”總結

來源:互聯網
上載者:User

經常看到如下代碼:

#ifdef _cplusplus

extern "C" {

#endif

#include "XXX.h"

#ifdef _cplusplus

}

#endif

解釋:

這段代碼的含義是,如果當前的程式是C++程式,那麼下面引用的標頭檔是C檔案, 那如果當前程式不是C++呢?難道包含的就不是C檔案了嗎?當然不是,不管當前程式是什麼,這個XXX.h都是一個C檔案

那為什麼還要多此一舉呢?

原因:

C++為了支援函數重載,將編譯後的函數名做了重整(mangled name),比如下面的函數

int add(int a, int b) ;

在C中編譯完的名字就是add,而在C++中,編譯完就變成了add_int_int(舉例而已,實際因編譯器而異),這樣在函數名字後面加上參數的類型,就可以區分不同的重載函數了,比如還有另一個函數

float add(float a, float b) ;

在C++中,它會被編譯成add_float_float,這就是C++區分重載函數的機制

可是問題也隨之而來

C++進行名字重整,而C不進行重整。當C++程式引用C的函數時,它會按照重整後的名字去目標檔案(.obj)中去尋找對應的函數,而目標檔案中存放的卻是C版本的函數,名字對不上,所以根本找不到!

怎麼辦呢?

這就是extern “C” 存在的一個原因了

它告訴C++,包含在extern “C”{ //…}塊中的東西是C版本的,你編譯的時候不要進行名字重整,否則你連結的時候就無法找到我!

於是上面的代碼也就不難理解了,光說不練是扯淡,上代碼

我們簡單的定義一個C標頭檔和實現檔案,只包含一個add函數

CClass.h 內容如下

#ifndef __CClass_H__

#define __CClass_H__

extern int add(int a, int b) ;

#endif // end __CClass_H__

CClass.c 內容如下

#include "CClass.h"

int add(int a, int b)

{

return a + b ;

}

下面我們用一個C++程式來引用這個C檔案

main.cpp 內容如下

#define _cplusplus // 為了測試,強加一句

#ifdef _cplusplus

extern "C" {

#endif

#include "CClass.h"

#ifdef _cplusplus

}

#endif

#include <iostream>

using namespace std ;

int main(void)

{

int result = add(1, 2) ;

cout << result << endl ;

system("pause") ;

return 0 ;

}

如果沒有#include <iostream>之前那些代碼而只是僅僅包含

#include "CClass.h"一句

你就會得到下面的錯誤

error LNK2019:unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main

顯然這是一個連結錯誤,因為找不到對應的函數定義

當然你也可以簡寫成下面的形式,直接在extern “C”塊中包含你想調用的函數

extern "C"

{

int add(int a, int b) ;

};

#include <iostream>

using namespace std ;

int main(void)

{

int result = add(1, 2) ;

cout << result << endl ;

system("pause") ;

return 0 ;

}

這在C++程式中是沒有問題的,但是如果是在C程式中,則會出現編譯錯誤,因為C中不允許extern “C”出現

另一個需要extern “C”的場合是當C程式調用C++的東西時

按照如下步驟做即可

1. 在C++的.h檔案中用extern “C”{}聲明將被C程式使用的函數

2. 在C++的.cpp檔案中實現上面的函數

3. 在.c檔案中用extern聲明要使用的C++函數

4. 使用即可

注意:切不可在.c檔案中包含C++的.h檔案,那樣編譯無法通過

上代碼:

CPPClass.h中聲明add函數

#ifndef __CPPClass_H__

#define __CPPClass_H__

extern "C"

{

int add(int a, int b) ;

};

#endif // end __CPPClass_H__

CPPClass.cpp實現add函數

#include "CPPClass.h"

int add(int a, int b)

{

return a + b ;

}

main.c 內容如下

#include <stdio.h>

//#include "CPPClass.h" // 不要包含標頭檔,否則編譯不過

extern int add(int a, int b) ; // 只需顯示聲明要調用的函數即可

int main(void)

{

int result = add(1, 2) ; //使用函數

printf("%d", result) ;

return 0 ;

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.