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++ 函数。

相关推荐
LuckyRich113 分钟前
【cpp-httplib】 安装与使用
c++·http
中微子17 分钟前
从C++看JavaScript闭包:执行上下文与作用域的跨语言对比
前端·c++
希望_睿智30 分钟前
实战设计模式之建造者模式
c++·设计模式·架构
@曲终1 小时前
C++:栈帧、命名空间、引用
java·开发语言·c++·经验分享·笔记
強云1 小时前
原子操作(C++)
c++
敲代码的瓦龙2 小时前
C++?多态!!!
c语言·开发语言·c++·windows·后端
我不是程序猿儿2 小时前
【C++】C++面向对象设计的核心思想之一: 接口抽象、解耦和可扩展性
java·开发语言·c++
~山有木兮3 小时前
new和delete的理解
c++·算法
whoarethenext3 小时前
使用 C/C++ 和 OpenCV 调用摄像头
c语言·c++·opencv
Dovis(誓平步青云)3 小时前
探索C++标准模板库(STL):从容器到底层奥秘-全面解析String类高效技巧(上篇)
开发语言·c++·stl·string