【嵌入式底层知识修炼】C/C++混合编程之extern "C"的含义和使用


C和C++从来都没有截然分开过,它们是嵌入式的孪生兄弟

————CSDN根号3


01 - C/C++混合编程

  C++一直都被调侃为带类的C,可见C++与C是密不可分的。
  目前C和C++垄断嵌入式编程,如果产品带显示屏或者有操作系统,那么一般都离不开C++编程,因为显示屏和操作系统属于上层APP的使用,越是上层编程,越需要面向对象思维和相关编译器支持,因为上层经常变动,使用模块化编程将难以维护。

Alt

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源码中
Alt

  这些强大的库或者源码使用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_intfun_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标准去编译
  • 重载本质上只是编译器为其取了一个独一无二的名字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值