extern “C”总结
學(xué)了就忘,忘了再學(xué)。有時(shí)感覺自己幾乎就是一個(gè)跳梁小丑。沒有辦法,只好多記些筆記。
本文版權(quán)歸作者和博客園共有 FROM: http://www.cnblogs.com/graphics/archive/2010/12/24/1916343.html |
經(jīng)常看到如下代碼:
#ifdef _cplusplus extern "C" { #endif #include "XXX.h" #ifdef _cplusplus } #endif |
解釋:
extern "C"的作用是,告訴C++編譯器,下面的代碼按照C的方式進(jìn)行編譯,說白了,不要對這些函數(shù)進(jìn)行名字重整(function name mangling)。通常在C++程序中使用C函數(shù)或者模塊時(shí),需要用到這個(gè)功能。
原因:
C++為了支持函數(shù)重載,將編譯后的函數(shù)名做了重整(mangled name),比如下面的函數(shù)
int add(int a, int b) ; |
在C中編譯完的名字就是add,而在C++中,編譯完就變成了add_int_int(舉例而已,實(shí)際因編譯器而異),這樣在函數(shù)名字后面加上參數(shù)的類型,就可以區(qū)分不同的重載函數(shù)了,比如還有另一個(gè)函數(shù)
float add(float a, float b) ; |
在C++中,它會(huì)被編譯成add_float_float,這就是C++區(qū)分重載函數(shù)的機(jī)制
可是問題也隨之而來
C++進(jìn)行名字重整,而C不進(jìn)行重整。當(dāng)C++程序引用C的函數(shù)時(shí),它會(huì)按照重整后的名字去目標(biāo)文件(.obj)中去尋找對應(yīng)的函數(shù),而目標(biāo)文件中存放的卻是C版本的函數(shù),名字對不上,所以根本找不到!
怎么辦呢?
這就是extern “C” 存在的一個(gè)原因:
它告訴C++,包含在extern “C”{ //…}塊中的東西是C版本的,你編譯的時(shí)候不要進(jìn)行名字重整,否則你鏈接的時(shí)候就無法找到我!
于是上面的代碼也就不難理解了,光說不練是扯淡,上代碼
我們簡單的定義一個(gè)C頭文件和實(shí)現(xiàn)文件,只包含一個(gè)add函數(shù)
CClass.h 內(nèi)容如下
#ifndef __CClass_H__ #define __CClass_H__ extern int add(int a, int b) ; #endif // end __CClass_H__ |
CClass.c 內(nèi)容如下
#include "CClass.h" int add(int a, int b) { return a + b ; } |
下面我們用一個(gè)C++程序來引用這個(gè)C文件
main.cpp 內(nèi)容如下
#define _cplusplus // 為了測試,強(qiáng)加一句 #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"一句
你就會(huì)得到下面的錯(cuò)誤
error LNK2019:unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main
顯然這是一個(gè)鏈接錯(cuò)誤,因?yàn)檎也坏綄?yīng)的函數(shù)定義
當(dāng)然你也可以簡寫成下面的形式,直接在extern “C”塊中包含你想調(diào)用的函數(shù)
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程序中,則會(huì)出現(xiàn)編譯錯(cuò)誤,因?yàn)镃中不允許extern “C”出現(xiàn)
另一個(gè)需要extern “C”的場合是當(dāng)C程序調(diào)用C++的東西時(shí)
按照如下步驟做即可
1. 在C++的.h文件中用extern “C”{}聲明將被C程序使用的函數(shù)
2. 在C++的.cpp文件中實(shí)現(xiàn)上面的函數(shù)
3. 在.c文件中用extern聲明要使用的C++函數(shù)
4. 使用即可
注意:切不可在.c文件中包含C++的.h文件,那樣編譯無法通過
上代碼:
CPPClass.h中聲明add函數(shù)
#ifndef __CPPClass_H__ #define __CPPClass_H__ extern "C" { int add(int a, int b) ; }; #endif // end __CPPClass_H__ |
CPPClass.cpp實(shí)現(xiàn)add函數(shù)
#include "CPPClass.h" int add(int a, int b) { return a + b ; } |
main.c 內(nèi)容如下
#include <stdio.h>
//#include "CPPClass.h" // 不要包含頭文件,否則編譯不過
extern int add(int a, int b) ; // 只需顯示聲明要調(diào)用的函數(shù)即可
int main(void)
{
int result = add(1, 2) ; //使用函數(shù)
printf("%d", result) ;
return 0 ;
}
總結(jié)
以上是生活随笔為你收集整理的extern “C”总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 导出类图
- 下一篇: vs2010 sp1 安装 Silver