0. 说明
- C++采用g++编译,C采用gcc编译。两者主要不同点是:C++编译考虑到函数重载,会将原函数“改名”(命名倾轧name mangling);而在C中不存在重载,函数名不会变动。
- g++和gcc可以兼容C++和C的编译方式,但是默认情况下g++采用C++编译方式;而gcc采用C的编译方式
- 注意:gcc编译C++文件时不会主动链接C++用到的库stdc++,需要手动指定链接选项
-lstdc++
__cplusplus
宏定义会在编译cpp文件以及用C++的方式编译时被包含,因此用gcc编译.cpp文件或者g++编译.c、.cpp文件都会有这个宏
- 之所以用条件判断,因为gcc不认识
extern "C"
,直接编译会报错
1. C++调用C
只需要声明时包含extern "C"
即可。下面的代码中,func.h可以不动,在main.cpp调用时,直接extern "C" int func(int, int)
也是可以的。只需要让编译器按照C的方式编译,不要改动函数名即可正确链接的函数符号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #ifndef FUNC_H #define FUNC_H
#ifdef __cplusplus extern "C" { #endif
int func(int, int);
#ifdef __cplusplus } #endif
#endif
|
1 2 3 4 5 6
| #include "func.h"
int func(int a, int b) { return a + b; }
|
1 2 3 4 5 6 7
| #include <iostream> #include "func.h"
int main() { std::cout << func(1, 3) << std::endl; }
|
2. C调用C++
C调用C++稍微麻烦点,遇到类函数和重载函数往往需要嵌套一层,详细如下。
2.1. 普通函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #ifndef FUNC_H #define FUNC_H
#ifdef __cplusplus extern "C" { #endif
void func();
#ifdef __cplusplus } #endif
#endif
|
1 2 3 4 5 6 7
| #include "func.h" #include <iostream>
void func() { std::cout << "void func()" << std::endl; }
|
1 2 3 4 5 6
| #include "func.h"
int main() { func(); }
|
2.2. 重载函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #ifndef ADAPTER_H #define ADAPTER_H
#ifdef __cplusplus extern "C" { #endif
void func_(); void func_i(int);
#ifdef __cplusplus } #endif
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include "func.h" #include <iostream>
void func() { std::cout << "void func()" << std::endl; }
void func(int a) { std::cout << "void func(int)" << std::endl; }
void func_() { func(); }
void func_i(int a) { func(a); }
|
1 2 3 4 5 6 7
| #include "func.h"
int main() { func_(); func_i(1); }
|
2.3. 类函数
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef CIRCLE_H #define CIRCLE_H
class Circle { double radius; public: Circle(double r) :radius(r) {} double getArea(); };
#endif
|
1 2 3 4 5 6
| #include "Circle.h"
double Circle::getArea() { return 3.1415926 * radius * radius; }
|
核心文件(adapter.h),此代码必须在C ++和C文件中都可以编译。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #ifndef ADAPTER_H #define ADAPTER_H
#ifdef __cplusplus extern "C" { #endif
void* Circle_new(double); double Circle_getAea(void*); void Circle_detete(void*);
#ifdef __cplusplus } #endif
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include "adapter.h" #include "Circle.h"
void* Circle_new(double r) { Circle *p = new Circle(r); return (void*)p; }
double Circle_getAea(void* p) { return ((Circle*)p)->getArea(); }
void Circle_detete(void* p) { Circle* cp = (Circle*)p; delete cp; }
|
1 2 3 4 5 6 7 8 9
| #include <stdio.h> #include "adapter.h"
int main() { void* p = Circle_new(1); printf("%lf\n", Circle_getAea(p)); Circle_detete(p); }
|
3. 参考