文章目录
C和C++从来都没有截然分开过,它们是嵌入式的孪生兄弟
————CSDN根号3
01 - C/C++混合编程
C++一直都被调侃为带类的C,可见C++与C是密不可分的。
目前C和C++垄断嵌入式编程,如果产品带显示屏或者有操作系统,那么一般都离不开C++编程,因为显示屏和操作系统属于上层APP的使用,越是上层编程,越需要面向对象思维和相关编译器支持,因为上层经常变动,使用模块化编程将难以维护。
02 - extern "C"的常见场合
在一些嵌入式强大的库或者源码中,随处可见extern "C"
的身影:
stm标准库system_stm32f4xx.h中
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t SystemCoreClock;
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
FreeRTOS源码中
这些强大的库或者源码使用extern "C"
的目的是:被C调用,或,调用C
03 - extern "C"的由来、含义和使用
3.1 - extern "C"的由来
如果你要问我C和C++的区别,我会站在上帝(编译器)的肩膀说:它们的上帝不一样。C++编译器为了更好地支持面向对象编程、支持重载,而对函数和变量的编译方式与C是不一样的,本质上,重载是编译器为函数或变量起了另一个独一无二的名字。
例如函数,fun(int a, int b)
和fun(char a, char b)
,C++编译后的函数名字大概是fun_int_int
和fun_char_char
,包含了函数名和参数类型。而C的编译只包含函数名,所以就fun(int a)
而言,C编译后的函数名字大概是_fun
,而C++编译后的函数名字大概是fun_int
例如变量,C++支持一个与任何类都无关的全局变量,如果类中有局部变量与之同名是允许的,它们是用.
区分的,全局变量不需要,而类中局部变量需要,重载的最后结果也是编译器为其取了一个独一无二的名字。
综上,C和C++是不能相互直接调用对方所编写的函数或变量,因为编译机制不一样,所以如果要混编,就要在C++中使用extern "C"
声明这些变量/函数的编译方式是属于C的,另外,如果C要调用C++的变量/函数,并不是在C中使用extern “C++”
,而是依然在C++中使用extern "C"
声明一些被C调用的函数或变量,总之,extern "C"只用在C++里面。
3.2 - extern "C"的含义
extern "C"
只出现在C++程序中,具体有两个含义:
第一个含义是extern
,表示被extern "C"
限定的变量/函数是extern
类型的
第二个含义是“C”
,表示被extern "C"
修饰的变量/函数是按照 C语言方式编译和连接的
简单来说,告诉C++编译器,这些外部变量\函数使用C语言的标准去编译。
3.3 - extern "C"的使用
为了确保使用extern "C"
的程序是C++程序,都会添加一个宏编译,C++编译器会自动定义一个宏__cplusplus
,所以只要检查有没有这个宏,就可以区分C和C++程序,总体框架如下:
#ifdef __cplusplus
extern "C" {
#endif
/* 变量声明 or 函数声明 or 头文件*/
#ifdef __cplusplus
}
#endif
C++调用C例子:
<b.cpp>
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
#include "a.h"
#ifdef __cplusplus
}
#endif
int main(void)
{
cout << sum(1,2) << endl;
return 0;
}
<a.h>
#ifndef _A_H
#define _A_H
int sum(int a, int b);
#endif
<a.c>
#include "a.h"
int sum(int a, int b)
{
return (a+b);
}
使用g++编译器编译a.c和b.cpp文件,生成可执行文件,运行后得到3
C调用C++例子:
<b.h>
#ifndef _B_H
#define _B_H
#ifdef __cplusplus
extern "C"{
#endif
}
int sum(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
<b.cpp>
#include "b.h"
int sum(int a, int b)
{
return (a+b);
}
<a.c>
#include <stdio.h>
extern int sum(int a, int b);
int main(void)
{
printf("%d",sum(1,2));
return 0;
}
使用gcc编译器编译a.c和b.cpp文件,生成可执行文件,运行后得到3
04 - 总结
- C和C++混合编程是使用extern "C"进行的
- extern "C"只使用在C++程序中,告诉C++编译器这些内容用C标准去编译
- 重载本质上只是编译器为其取了一个独一无二的名字