【STM32】混编C与C++时,extern “C“的相关笔记

1 篇文章 0 订阅

以下是与Chatgpt的对话记录

1. extern "C"的作用是什么?

extern “C” 是一个关键字组合,用于告诉编译器按照 C 语言的约定来处理函数或变量的名称和调用方式。在 C++ 中,函数名和变量名由于支持函数重载特性而不同于 C 语言,它们被编译器进行了一定的名称修饰(Name Mangling)。因此,如果需要使用 C 语言编写的函数库,就需要使用 extern “C” 声明来显式地指定 C 语言的调用约定,以保证 C++ 能够正确地使用这些函数。

例如,在 C++ 中调用一个 C 函数:

extern "C" int add(int a, int b);  // 声明

int main()
{
    int sum = add(1, 2);  // 调用
    return 0;
}

通过 extern “C” 声明,编译器会按照 C 语言的传统方式来调用函数。这样就可以在 C++ 中使用 C 函数库,而无需考虑 C++ 名称修饰的问题。

2. 如何在.C中调用.C++的函数?

在 C 中调用 C++ 的函数时,由于 C++ 支持函数重载和命名空间(namespace)等特性,C++ 编译器会对函数名称进行修饰,导致无法直接使用 C 接口的函数。

因此,需要通过 extern “C” 关键字组合来告诉编译器按照 C 语言的方式对函数进行处理。具体地,需要在 C++ 函数的定义以及声明前添加 extern “C” 关键字组合,这样编译器就会生成不带名称修饰的符号名称。

例如,在 C++ 中定义如下的函数:

// add.h 文件
#ifndef ADD_H
#define ADD_H

#ifdef __cplusplus
extern "C"
#endif
int add(int a, int b);

#endif

// add.cpp 文件
#include "add.h"

int add(int a, int b)
{
    return a + b;
}

其中,#ifdef __cplusplus 和 #endif 之间的代码用于保证在 C++ 中包含该头文件时,会自动加入 extern “C” 的声明。在 C 文件中使用该头文件时,则不会自动加入 extern “C” 声明,需要手动添加。

然后,在 C 中使用该函数时,只需包含 add.h 头文件即可:

// main.c 文件
#include <stdio.h>
#include "add.h"

int main()
{
    int sum = add(1, 2);
    printf("sum = %d\n", sum);
    return 0;
}

这样,就可以在 C 程序中使用 C++ 的函数了。

3. 重载函数如何在.C中调用

对于 C++ 中的函数重载,可以使用 extern “C” 关键字组合来进行处理。为了区分不同版本的函数,需要在函数名称后面添加参数类型和个数的信息。

例如,对于以下的 C++ 函数:

// add.h 文件
#ifndef ADD_H
#define ADD_H

#ifdef __cplusplus
extern "C"
#endif
int add(int a, int b);

#ifdef __cplusplus
extern "C"
#endif
double add(double a, double b);

#ifdef __cplusplus
extern "C"
#endif
float add(float a, float b);

#endif

// add.cpp 文件
#include "add.h"

int add(int a, int b)
{
    return a + b;
}

double add(double a, double b)
{
    return a + b;
}

float add(float a, float b)
{
    return a + b;
}

其中,每个版本的函数名称都一样,但参数类型和个数不同,因此需要通过添加外部链接指示器(External Linkage Specifier)来区分它们。在 Windows 平台上,通常使用以下的命名约定:

无符号修饰:_stdcall
有符号修饰:__cdecl
因此,在 add.h 中添加以下的声明:

// add.h 文件
#ifndef ADD_H
#define ADD_H

#ifdef __cplusplus
extern "C"
#endif
int __cdecl add_int(int a, int b);

#ifdef __cplusplus
extern "C"
#endif
double __cdecl add_double(double a, double b);

#ifdef __cplusplus
extern "C"
#endif
float __cdecl add_float(float a, float b);

#endif

在 add.cpp 中,定义这三个函数的实现:

// add.cpp 文件
#include "add.h"

int __cdecl add_int(int a, int b)
{
    return a + b;
}

double __cdecl add_double(double a, double b)
{
    return a + b;
}

float __cdecl add_float(float a, float b)
{
    return a + b;
}

这样,在 C++ 中定义 extern “C” 标记并使用特殊的命名约定,就可以防止 C++ 编译器对函数名进行修饰,使得其名称与 C 语言兼容。在 C 中调用该函数时,只需要通过 add.h 头文件来包含这三个函数的声明即可。

注意,这种方法只适用于已知函数原型的情况下,而在不了解函数原型的情况下,还需要使用其他技术和工具来处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值