c++中extern "C"有什么用_C++与C语言混合编译说明

夜辰吖_9926

夜辰吖_9926

2025-11-20

1032人浏览

原创

extern "C"用于使C++编译器以C语言方式链接函数,避免因C++名字修饰导致的链接错误。在C++中调用C函数时,需用extern "C"包裹函数声明或头文件,确保符号按C规则生成;而在C中调用C++函数时,需在C++端定义extern "C"修饰的包装函数,且接口为C兼容形式(不含类、引用等)。extern "C"有两种语法:单个函数声明或成组包含在花括号内。它仅影响链接属性,不改变语法特性,不能在其中使用C++特有构造。常见应用场景包括调用C库(如OpenSSL)、嵌入式开发、系统接口编程及编写供C调用的C++模块。系统头文件通常已内部处理extern "C",无需重复添加。正确使用extern "C"可有效解决跨语言混合编译中的符号解析问题。

c++中extern \

extern "C" 的主要作用是让 C++ 编译器以 C 语言的方式去处理函数或变量的链接,解决 C++ 和 C 混合编译时的链接问题。由于 C++ 支持函数重载、类等特性,它会对函数名进行“名字修饰(name mangling)”,而 C 语言不会。如果不加处理,C++ 代码中调用 C 函数,或 C 代码中调用 C++ 函数时,链接器会因找不到匹配的符号而报错。

一、C++ 调用 C 函数的方法

当在 C++ 代码中使用 C 语言编写的函数(比如来自 C 静态库或头文件),需要告诉 C++ 编译器:这些函数的名字不要做 name mangling,按 C 的方式链接。

  • 使用 extern "C" 包裹 C 函数的声明
  • 通常用于包含 C 头文件时

例如,有一个 C 语言头文件 my_c_lib.h:

// my_c_lib.h
void c_function(int x);
int  add(int a, int b);

在 C++ 文件中引用时,应这样写:

// main.cpp
extern "C" {
#include "my_c_lib.h"
}

或者逐个声明:

extern "C" void c_function(int x);
extern "C" int  add(int a, int b);

这样,C++ 编译器就会用 C 的命名规则查找这些函数,链接时能正确找到由 C 编译生成的目标符号。

二、C 调用 C++ 函数的限制与方法

C 语言无法直接调用 C++ 函数,因为 C 不理解 name mangling,也不支持类、重载等特性。但可以通过一些技巧实现有限调用:

  • 在 C++ 中定义一个被 extern "C" 修饰的包装函数
  • 该函数必须使用 C 兼容的接口(不能用引用、类等)
  • C 代码通过这个包装函数间接调用 C++ 功能

示例:

Livestream Script Generator
Livestream Script Generator

直播带货脚本:话术、节奏、互动、促单。适用于主播、电商运营、MCN机构。

下载
// wrapper.cpp
#include <iostream>

class MyClass {
public:
    void greet() { std::cout <p>C 代码中可以这样调用:</p>
<pre class="brush:php;toolbar:false;">// main.c
extern void call_cpp_greet();

int main() {
    call_cpp_greet();
    return 0;
}

编译时需用 C++ 编译器处理 C++ 文件,C 编译器处理 C 文件,最后一起链接。

三、extern "C" 的语法形式

支持两种写法:

extern "C" void func();  // 声明单个函数

或成组声明:

extern "C" {
    void func1();
    int  func2(int a, int b);
    #include "c_header.h"
}

注意:extern "C" 只影响链接方式,不改变语言语法。你不能在 extern "C" 块里定义 C++ 特性(如类、重载函数)。

四、常见应用场景

  • 调用操作系统或嵌入式平台提供的 C 接口(如 POSIX、STM32 HAL)
  • 使用 C 编写的第三方库(如 OpenSSL、libcurl)
  • 编写供 C 调用的 C++ 模块(如动态库导出函数)
  • 在 C++ 项目中包含标准 C 头文件(如 string.h、stdio.h),虽然通常已由系统头文件内部处理

基本上就这些。extern "C" 是混合编程的关键工具,理解它有助于避免链接错误,特别是在跨语言协作或底层开发中非常实用。

13万字C语言保姆级教程(深入):立即使用
在学习笔记中,你将探索c语言的核心概念和高级技巧!

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6919

3

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3208

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

5169

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3849

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

486

15

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

80

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

60

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

220

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习