extern "C"與C++中的C函數調用(2)

  前面已經深刻了解過extern "C"了,下面進一步探討一下extern 「C」的使用方法。ios

一、  C代碼中包含extern 「C」,C代碼沒法經過編譯([1]中C++中調用C的方法1錯誤)函數

  代碼以下:spa

//C代碼頭文件CDemo.h
#include <stdio.h>
#ifndef C_SRC_DEMO_H  
#define C_SRC_DEMO_H  
extern "C" int f(int x,int y);
#endif  // C_SRC_DEMO_H

 

//C代碼CDemo.c
#include "CDemo.h"

int f(int x,int y)
{
        printf("In C file\n");
        printf("x + y = %d\n",x+y);
        return 0;
}

  在Linux下,$:gcc  –c  CDemo.c 編譯通不過code

  出錯信息以下:blog

  

  結論:在C語言的頭文件中,對其外部函數只能指定爲extern類型,C語言中不支持extern "C"聲明,在.c文件中包含了extern "C"時會出現編譯語法錯誤。編譯器

 

二、  若是在C頭文件中函數聲明瞭函數(f(int x,int y))爲extern類型,而在C++中包含該頭文件後,再從新聲明並添加上extern "C"(extern int f( int x, int y )),C++文件編譯通不過([1]中C++中調用C的方法2錯誤)io

代碼以下: 編譯

//C代碼頭文件CDemo.h
#include <stdio.h>
#ifndef C_SRC_DEMO_H  
#define C_SRC_DEMO_H  
extern int f(int x,int y);
#endif  // C_SRC_DEMO_H

 

//C代碼 CDemo.c
#include "CDemo.h"

int f(int x,int y)
{
        printf("In C file\n");
        printf("x + y = %d\n",x+y);
        return 0;
}

 

//C++代碼 cppDemo.cpp
#include "CDemo.h"
#include <iostream>
extern "C" int f(int x,int y);

int main()
{
        f(2,3);
        return 0;
}

  在Linux下,$:gcc  -c  CDemo.c 能夠經過,並生成CDemo.o文件class

  $:g++  -c  cppDemo.cpp 編譯出錯stream

  出錯信息:

  

可是還要注意一下兩點:

(1)若是不從新聲明,即C++代碼更改成以下:

//C++代碼 cppDemo.cpp
#include "CDemo.h"
#include <iostream>

int main()
{
        f(2,3);
        return 0;
}

  編譯能夠經過,可是將兩個.o文件連接起來生成可執行文件時,會出錯執行狀況以下:

  $g++  cppDemo.o CDemo.o –o cppDemo

  

  這說明C++文件沒有找到定義在C文件中的f函數,這是由於該函數被C編譯器編譯後在符號庫中的名字與C++編譯器產生的名字不一樣,如, C編譯器產生的函數f的符號庫中的名字爲:f,而C++編譯器產生的爲_Z1fii(不一樣的編譯器可能生成的名字不一樣,可是都採用了相同的機制,生成的新名字稱爲「mangled name」)。

(2)不管C代碼中聲明有沒有包含關鍵字extern,只要C++中有extern 「C」,連接時便不會出錯。

參考文獻:

[1] 《編寫高質量代碼:改善C++程序的150個建議》,建議19:明白在C++中如何使用C

相關文章
相關標籤/搜索