C/C++中 的extern "C"

#ifdef __cplusplus
extern "C" {
#endif

extern  double reciprocal (int i); 
 
#ifdef __cplusplus
}
#endif

看到了如上一段代碼(《Advance Linux Programming》 代碼列表1.3),從如下幾個方面解讀一下:函數

  1. #ifdef __cplusplus/ #endif
  2. extern 關鍵字
  3. extern "C"

1.#ifdef / #endif

  #ifdef xxx 至關於#if defined(xxx),用於條件編譯,若xxx已經被宏定義,那麼編譯包括其後的各行,直到遇到#endif,#elif,#else語句爲止。spa

  __cplusplus是C++的自定義宏,若是定義了這個宏說明這是一段C++代碼。blog

  以上代碼的意思就是若是這是一個cpp文件,那麼編譯器就執行extern "C"{}語句。ip

  另外在C/C++中經常使用#ifndef xxx/#endif來避免重複的定義,#ifndef xxx至關於#if !defined(xxx)。內存

 

2.extern關鍵字

  extern用來聲明變量,該關鍵字告訴編譯器,其聲明的變量和函數能夠在本模塊使用。ci

  用extern時僅僅聲明變量而不分配內存空間。在一個項目中函數,變量等在全部源文件中必須保持一致,除非指定定義爲局部的,全局變量在全部模塊中只能定義一次,能夠聲明屢次,但聲明類型必須保持一致。編譯器

  注:C語言中的定義和聲明:源碼

  聲明:io

extern int x;
extern int g(int);
int f(int, int);

  聲明只指定標識符,不分配空間。編譯

  函數的聲明能夠省略extern關鍵字,但加上extern關鍵字能夠知道該函數可能在其餘模塊定義過。

  定義:

int x;
int g(int x, int y){ return x + y;}

  定義是對聲明的實現或實例化。

 

3.extern "C"

  C和C++編譯的區別:C++爲了支持函數重載,在將代碼編譯到二進制文件後,函數fun(int)的函數名其實已經變成了相似fun_int這種形式,這時調用fun()函數如fun(2)就對應fun_int(2),而在C語言中是沒有重載的,這樣C文件在和C++混合編譯的時候就會報鏈接錯誤。

  "C"表示了一種編譯和鏈接的規約,extern "C"則給代碼指定了這種規約,並且不影響語義。函數聲明中聲明指定了extern "C",仍要遵照C++的語法規則,如類型檢測參數轉換等。

  若是有多句代碼須要加上extern "C",能夠將它們放到extern "C" {}中。

 

《Advanced Linux Programming》中第一節的示例就用了extern "C"實現了在C語言中調用C++函數:

代碼列表 1.1 ( main.c ) C源碼—— main.c

#include <stdlib.h> 
#include <stdio.h> 
#include 「reciprocal.hpp」  
int main (int argc, char **argv) {
    int i;  
i = atoi (argv[1]); printf (「The reciprocal of %d is %g\n」, i, reciprocal (i)); return 0; }

代碼列表 1.2 ( reciprocal.cpp ) C++ 源碼—— reciprocal.cpp

#include <cassert> 
#include 「reciprocal.hpp」  
double reciprocal (int i) {
    // i 不能爲 0
    assert (i != 0);
    return 1.0/i; 
}

代碼列表 1.3 ( reciprocal.hpp )包含文件—— reciprocal.hpp

#ifdef __cplusplus
extern "C" {
#endif

extern  double reciprocal (int i); 
 
#ifdef __cplusplus
}
#endif
相關文章
相關標籤/搜索