C++中的extern "C" {}

 

      说明:本文主要内容参考了吴秦(Tyler)的博客,并结合自己的情况,做了一些修改。如果想了解更多的规则,请参考吴秦(Tyler)的博客。

      最近在做QT和DVSDK的混合编程,找到了一个嵌入式超声波检测仪的例子来学习(MIDAS Ultrasound v3.0 Demo),里面的头文件很多都是类似于如下声明:

C++中的extern "C" {}_第1张图片

      宏 #ifndef 、#define、#endif 的作用大家肯定都非常了解了,主要是为了防止在一个项目中,头文件被多次包含。本文简单讨论一下 extern "C" { } 的作用。

      extern "C"  的作用是实现类C(代表的是跟C语言的编译和连接方式一致的所有语言)和C++的混合编程

      要明白 C 和 C++ 的互相调用,你得知道它们之间的编译和连接差异。

      1、C++ 的编译和连接机制

      C++是一个面向对象语言(虽不是纯粹的面向对象语言),它支持函数的重载,重载这个特性给我们带来了很大的便利。为了支持函数重载的这个特性,C++编译器实际上将下面这些重载函数:

      这样的函数名,来唯一标识每个函数。注:不同的编译器实现可能不一样,但是都是利用这种机制。所以当连接是调用 print(3) 时,它会去查找 _print_int(3) 这样的函数。下面说个题外话,正是因为这点,重载被认为不是多态,多态是运行时动态绑定(“一种接口多种实现”),如果硬要认为重载是多态,它顶多是编译时“多态”。

      C++中的变量,编译也类似,如全局变量可能编译g_xx,类变量编译为c_xx等。连接是也是按照这种机制去查找相应的变量。

      2、C 的编译和连接机制     

      C语言中并没有重载和类这些特性,故并不像C++那样 print(int i) ,会被编译为 _print_int ,而是直接编译为 _print 等。因此如果直接在C++中调用C的函数会失败,因为连接是调用C中的 print(3) 时,它会去找 _print_int(3) 。因此 extern "C" 的作用就体现出来了。

      了解了C和C++的编译机制,接下来,我们就分别介绍如何在C++中调用C的代码、C中调用C++的代码。

      1、C++ 中调用 C 的代码

      假设一个C的头文件 cHeader.h 中包含一个函数 print(int i) :

C++中的extern "C" {}_第2张图片

      相应的实现文件 cHeader.c 的代码为:

C++中的extern "C" {}_第3张图片

      现在在C++的代码文件 main.cpp 中引用C中的 print(int i) 函数:

C++中的extern "C" {}_第4张图片

      执行程序输出:

     

      2、C 中调用 C++ 的代码

      现在换成在C中调用C++的代码,这与在C++中调用C的代码有所不同。如下在 cppHeader.h 头文件中定义了下面的代码:

C++中的extern "C" {}_第5张图片  

      相应的实现文件cppHeader.cpp文件中代码如下:

C++中的extern "C" {}_第6张图片

      在C的代码文件 main.c 中调用 print 函数:

 C++中的extern "C" {}_第7张图片

      注意在C的代码文件中直接 #include "cppHeader.h" 头文件,编译出错。而且如果不加 extern void print(int i) 编译也会出错。

你可能感兴趣的:(C++中的extern "C" {})