C++ | extern “C“

在 C++ 编程中,extern "C"是一个非常重要的特性,它主要用于解决 C++ 与 C 代码之间的相互调用问题。本文将深入探讨extern "C"的作用、使用原因以及具体的使用方法。

一、extern "C" 的作用

extern "C"的主要作用是告诉 C++ 编译器,按照 C 语言的方式来编译和链接指定的代码。在 C++ 中,函数名会被编译器进行名字改编(Name Mangling),这是为了支持函数重载等特性。而 C 语言没有函数重载,函数名不会被改编。当我们需要在 C++ 代码中调用 C 语言编写的函数,或者在 C 语言代码中调用 C++ 编写的函数时,就需要使用extern "C"来确保函数名在编译和链接过程中的一致性。

C++ 中函数名修饰的格式和规则

C++ 的名字修饰规则,是为了让编译器能够区分同名但参数列表不同的函数,进而实现函数重载。不同的编译器,其名字修饰规则可能存在差异 ,这里以常见的 GCC 编译器为例展开说明。需注意,实际的修饰规则在不同版本编译器以及不同编译选项下可能有所变化,以下展示的规则不一定完全正确,但基本遵循这个思路。。

对于一个简单的函数定义:

void func(int a, double b);

GCC 编译器可能会将其修饰为类似这样的形式:

_Z4funcid

其中:

  • _Z是名字修饰的前缀,是 GCC 编译器的约定。
  • 4表示函数名func的长度。
  • func即原函数名。
  • i表示第一个参数是int类型。
  • d表示第二个参数是double类型。

如果函数是类的成员函数,情况会更复杂一些。例如:

class MyClass {

public:

void memberFunc(int a, double b);

};

其修饰后的名字可能类似:

_ZN7MyClass9memberFuncidE

这里:

  • _Z同样是前缀。
  • N表示接下来是一个命名空间或者类的名字。
  • 7表示类名MyClass的长度。
  • MyClass是类名。
  • 9表示成员函数名memberFunc的长度。
  • memberFunc是成员函数名。
  • i和d含义同前,分别表示参数类型。
  • E表示名字结束。

这种复杂的名字改编机制,使得编译器能够在编译和链接阶段准确区分不同的函数,即使它们名字相同,只要参数列表不同就能被正确识别。但在 C 语言中,由于没有这种需求,函数名就是简单的标识符,不进行如此复杂的改编 。这就是为什么在 C++ 与 C 语言混合编程时,需要extern "C"来消除这种差异。

二、使用 extern "C" 的原因

兼容性:在实际项目中,很多成熟的库都是用 C 语言编写的,例如一些操作系统底层的库、数学计算库等。C++ 作为一种更高级的语言,希望能够复用这些 C 语言库的代码。通过extern "C",C++ 可以无缝地调用 C 语言的函数,实现两者的兼容。

保持代码简洁:如果不使用extern "C",在 C++ 中调用 C 函数时,需要进行复杂的函数声明和链接设置,这会使代码变得繁琐。而extern "C"简化了这个过程,使代码更加简洁易读。

三、extern "C" 的使用方法

  1. 在 C++ 中调用 C 函数
    • 首先,编写一个 C 语言的源文件,例如c_function.c:

#include <stdio.h>

// C语言函数定义

void c_function() {

printf("This is a C function.\n");

}

  • 然后,在 C++ 源文件中调用这个 C 函数,例如cpp_main.cpp:

extern "C" {

// 声明要调用的C函数

void c_function();

}

int main() {

c_function();

return 0;

}

在这个例子中,extern "C"将c_function函数的声明按照 C 语言的方式进行处理,这样 C++ 编译器就能够正确地找到并调用这个 C 函数。

  1. 在 C 语言中调用 C++ 函数
    • 编写一个 C++ 的源文件,例如cpp_function.cpp:

#include <iostream>

// C++函数定义

extern "C" void cpp_function() {

std::cout << "This is a C++ function called from C.\n";

}

  • 然后,在 C 语言源文件中调用这个 C++ 函数,例如c_main.c:

// 声明要调用的C++函数

extern void cpp_function();

int main() {

cpp_function();

return 0;

}

这里cpp_function函数被声明为extern "C",这样 C 语言编译器就能够识别并调用这个 C++ 函数。

相关推荐
ん贤31 分钟前
【数据结构】栈与队列:基础 + 竞赛高频算法实操(含代码实现)
java·数据结构·c++·算法
萧萧玉树40 分钟前
设计模式-单一职责
开发语言·c++·设计模式
小林熬夜学编程1 小时前
【高并发内存池】第一弹---深入解析内存池:项目介绍、原理及设计定长内存池全攻略
linux·服务器·c语言·开发语言·c++·算法
郭涤生1 小时前
Chapter 2:auto_《Effective Modern C++》notes
开发语言·c++·笔记
刃神太酷啦2 小时前
算法基础篇(蓝桥杯常考点)
数据结构·c++·算法·蓝桥杯c++组
柯ran2 小时前
C++|构造函数和析构函数
开发语言·c++
闻缺陷则喜何志丹2 小时前
【数学 线性代数】差分约束
c++·线性代数·数学·差分约束·负环最短路
多思考少编码2 小时前
AtCoder Beginner Contest 397 A - D题解
c++·算法·atcoder·算法竞赛
奕天者2 小时前
C++学习笔记(二十一)——文件读写
c++·笔记·学习
江西理工大学小杨2 小时前
C++菱形继承内存模型
开发语言·c++·算法