先看下面这个例子:
#ifdef __cplusplus
extern "C"{
#endif
/*the something here*/
#ifdef __cplusplus
}
#endif
它到底有什么用呢,这样的问题会出现在面试or笔试中,我觉得作为一个学C++的,应该了解一下。下面从下面几个方面来介绍它:
1、条件编译:#ifdef _cplusplus / #endif _cplusplus 用法
2、extern "C" 用法
- 2.1、extern关键字
- 2.2、"C"
- 2.3、小结extern "C"
3、C和C++互相调用
- 3.1、C++的编译和连接
- 3.2、C的编译和连接
- 3.3、C++中调用C的代码
- 3.4、C中调用C++的代码
4、C和C++混合调用特别之处函数指针
5、几道的题目(问题)
1、条件编译:#ifdef _cplusplus/#endif _cplusplus 用法
在介绍extern "C"之前,我们来看下#ifdef _cplusplus/#endif _cplusplus的作用。很明显#ifdef/#endif、#ifndef/#endif用于条件编译,#ifdef _cplusplus/#endif _cplusplus表示如果定义了宏_cplusplus,就执行#ifdef/#endif之间的语句,否则就不执行。
在这里为什么需要#ifdef _cplusplus/#endif _cplusplus呢?这是C++的条件编译,是四种预编译命令之一(头文件包含,条件编译,宏替换和布局控制)!
既然说到了条件编译,我就介绍它的一个重要应用——避免重复包含头文件。为了防止头文件重复包含,在C++中,经常会使用到条件编译。
现在假设有如下场景:现有A, B, C三个头文件,它们之间的相互关系如下:文件B,C中会直接包含文件A,而文件C中同时会包含文件B,这样通过直接及间接包含,文件C包含了文件A两次, 通常编译的时候就会提醒变量重复定义等问题,这就是有重复包含导致的。C++中通过条件编译解决了这个问题,在文件C中第一次包含文件A时,不会有问题, 而当第二次包含时,条件编译起了作用,组织了重复包含,从而确保了程序的正确性。
下面是一个C++头文件,该头文件会被多个其他头文件包含,这里使用条件编译解决问题。
#ifndef TOKEN_H
#define TOKEN_H
#include <string>
using namespace std;
enum TokenType{NUMBER,OP,LPAREN,RPAREN,ERROR};
class Token
{
private:
//save the value and tokentype pair
string value;
TokenType tokenType;
public:
Token();
//get method for private memeber
string getValue();
Tokentype getTokenType();
//set method for private member
void setValue(string v);
void setTokenType(TokenType t);
};
#endif //TOKEN_H
2、extern "C"
首先从字面上分析extern "C",它由两部分组成——extern关键字、"C"。下面我就从这两个方面来解读extern "C"的含义。
2.1、extern关键字
以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。在C++中用extern关键字来声明变量和函数;对于函数而言,由于函数的声明如“extern int method();”与函数定义“int method(){}”可以很清晰的区分开来,为了简便起见,可以把extern关键字省略,于是有了我们常见的函数声明方式“int method();”,然而对于变量并非如此,变量的定义格式如“int i;”,声明格式为“extern int i;”,如果省略extern关键字,就会造成混乱,故不允许省略。
如下所示,在file2.cpp中f()使用的x和f()是定义在file1.h中的。extern关键字表明file2.cpp中x,仅仅是一个变量的声明,其并不是在定义变量x,并未为x分配内存空间。变量x在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。但是可以声明多次,且声明必须保证类型一致。注意,在file2.cpp中需包含file1.h。
//file1.h
int x=1;
int f()
{
return x++;
}
//file2.cpp
#include "file1.h"
extern int x;
int f();
void main()
{
x=f();
}
经本人测试,上面的程序可以省略掉“extern int x”和“int f()”,而只包含"#include "file1.h""。但是反过来不行,也就是:不可以省略掉"#include "file1.h"",而仅仅只包含“extern int x”和“int f()”,这样file2.cpp会找不到变量