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
相关文章
相关标签/搜索