1. 前情提要
1. 使用混合编程
混合使用C++和C代码是实际工程中不可避免的,虽然C++编译器能够兼容C语言的编译方式,但C++编译器会优先使用C++的方式进行编译。利用extern "C" 关键字可以强制让C++编译器以C的方式进行编译。
2. C和C++的编译规则不一样
C++支持函数重载,而C语言不支持。当函数分别被C++编译器和C编译器编译之后,因规则不同,编译之后的函数名字是不相同的。所以单单只以某个固定的方式同时编译*.c和*.cpp文件时,将会造成调用的一方找不到对应的函数名。
3. extern关键字
被extern "C" 限定的函数或变量是extern类型的。此意即,其即可以在本文件中被使用,也可以在其他文件中被使用。
2. C调用C++
此示例为三个程序文件,文件名分别为Mix.cpp,Mix.h,main.c。
/**************C++文件:Mix.cpp****************/
#include "Mix.h"
#include <iostream>
using namespace std;
Mix::Mix(int val)
{
a = val;
}
void Mix::fun()
{
cout << "The val is: " << a << endl;
}
void print()
{
Mix mix(10);
mix.fun();
}
/**************C++文件:Mix.h****************/
#ifndef _MIX_H_
#define _MIX_H_
class Mix
{
public:
Mix(int val);
void fun();
private:
int a;
};
#ifdef __cplusplus //当使用C++编译器编译Mix.cpp和Mix.h文件的时候,extern "C" 生效
extern "C" {
#endif
void print(); //对外接口
#ifdef __cplusplus
}
#endif
#endif
/**************C文件:main.c****************/
#include <stdio.h>
//#include "mix.h" //此处绝不可以将头文件添加进来,添加进来的意思就表示要用C编译器对class类进行编译,显然这是错误的!!!
extern void print();
void main()
{
print();
}
Windows环境下,上述三个文件可直接在VS中编译使用。若是在Linux环境下,下面给出了Makefile文件:
main.out : main.o Mix.o
g++ $^ -o $@
main.o : main.c
gcc -o $@ -c $^ #C文件使用gcc编译器进行编译
Mix.o : Mix.cpp
g++ -o $@ -c $^ #C++文件使用g++编译器进行编译
或使用以下命令:
g++ -c Mix.cpp -o Mix.o
gcc -lstdc++ main.c Mix.o -o main
3. C++调用C
此示例亦为三个程序文件,文件名分别为Mix.c,Mix.h,main.cpp。
/**************C文件:Mix.c****************/
#include "Mix.h"
void print()
{
printf("I'm C compiler!!!");
}
/**************C文件:Mix.h****************/
#ifndef _MIX_H_
#define _MIX_H_
extern void print();
#endif
/**************C++文件:main.cpp****************/
#include <iostream>
extern "C" { //调用时,只需将需要使用的头文件用extern "C" 包括即可。
#include "mix.h"
}
void main()
{
print();
}