extern “C“ in C++

English: extern "C" tells the C++ compiler to use C linkage for a declaration or definition, which mainly disables C++ name mangling.

中文: extern "C" 告诉 C++ 编译器:这个声明或定义要使用 C 链接方式 ,最主要的效果就是关闭 C++ 的名字重整

English: It does not mean "compile this file as C". It only changes symbol linkage.

中文: 它并不表示"把这个文件按 C 来编译",它只是改变符号链接方式

实验 1:.c.cpp 都用 g++ 编译

.c & .cpp both compile with g++

main.cpp

cpp 复制代码
#include <iostream>
#include "test.h"

// extern "C" void show();

void test01()
{
    show();
}

int main()
{
    test01();

    return EXIT_SUCCESS;
}

test.h

cpp 复制代码
#include <stdio.h>

void show();

test.c

cpp 复制代码
#include "test.h"

void show()
{
    printf("hello world.\n");
}

both get C++ linkage

g++ main.cpp test.c -o main

bash 复制代码
shaoyoulu@shaoyoulu:~/Code/extern$ g++ main.cpp test.c -o main
shaoyoulu@shaoyoulu:~/Code/extern$ ./main
hello world.

English: When you run g++ main.cpp test.c -o main, both files are compiled as C++ translation units. The .c suffix does not force C mode when the compiler is g++.

中文: 当你执行 g++ main.cpp test.c -o main 时,这两个文件都会被当成 C++ 翻译单元 编译。.c 后缀并不会强制让 g++ 进入 C 模式。

English: That is why the program works even without extern "C": both declaration and definition are C++ linkage, so they match.

中文: 这就是为什么即使没有 extern "C",程序也能运行:因为声明和定义都被当成 C++ 链接方式,所以符号是匹配的。

English: This experiment proves only one thing: g++ compiles .c files as C++ when you ask g++ to compile them.

中文: 这个实验只证明了一件事:当你让 g++ 去编译时,它会把 .c 文件也按 C++ 处理。

实验 2:main.cppg++test.cgcc,但没有 extern "C"

.cpp compile with g++, .c compile with gcc

without extern "C" void show();

bash 复制代码
shaoyoulu@shaoyoulu:~/Code/extern$ g++ -c main.cpp -o main.o
shaoyoulu@shaoyoulu:~/Code/extern$ gcc -c test.c -o test.o
shaoyoulu@shaoyoulu:~/Code/extern$ g++ main.o test.o -o main
/usr/bin/ld: main.o: in function `test01()':
main.cpp:(.text+0x9): undefined reference to `show()'
collect2: error: ld returned 1 exit status
shaoyoulu@shaoyoulu:~/Code/extern$ 

undefined reference to `show()'

English: This is the real mixed C/C++ test. gcc compiles test.c as C, so show has C linkage. g++ compiles main.cpp as C++, so show() in the declaration has C++ linkage by default.

中文: 这才是真正的 C/C++ 混合测试。gcctest.c 按 C 编译,所以 show 是 C 链接;g++main.cpp 按 C++ 编译,所以 show() 的声明默认是 C++ 链接。

English: The linker then sees two different symbols: one unmangled C symbol and one mangled C++ symbol. So it reports undefined reference to show().

中文: 于是链接器看到的是两个不同的符号:一个是未重整的 C 符号,一个是 C++ 重整后的符号,所以报 undefined reference to show()

实验 3:在 main.cpp 中加上 extern "C" void show();

with extern "C" void show();

main.cpp

bash 复制代码
#include <iostream>
//#include "test.h"

extern "C" void show();

void test01()
{
    show();
}

int main()
{
    test01();

    return EXIT_SUCCESS;
}
bash 复制代码
shaoyoulu@shaoyoulu:~/Code/extern$ g++ -c main.cpp -o main.o
shaoyoulu@shaoyoulu:~/Code/extern$ gcc -c test.c -o test.o
shaoyoulu@shaoyoulu:~/Code/extern$ g++ main.o test.o -o main
shaoyoulu@shaoyoulu:~/Code/part1/extern$ ./main 
hello world.
shaoyoulu@shaoyoulu:~/Code/extern$ 

English: Now the C++ compiler is told to treat show as a C-linked symbol. It no longer mangles the name, so the declaration matches the C definition compiled by gcc.

中文: 这时 C++ 编译器被告知:show 是 C 链接符号,不要重整名字。于是这个声明就能和 gcc 编译出来的 C 定义匹配上。

English: That is why the program links and runs correctly.

中文: 这就是为什么程序能正确链接并运行。

important concepts to emphasize

1 extern "C" 的本质

English: extern "C" is a linkage specification, not a storage class and not a compiler switch.

中文: extern "C" 是一种链接说明,不是存储类别,也不是编译器开关。

English: Its main purpose is to make C+±compiled code produce C-compatible symbols.

中文: 它的主要目的,是让 C++ 编译出来的代码生成 C 兼容的符号名


2 C++ 为什么需要它

English: C++ supports function overloading, namespaces, and more advanced type information, so it encodes extra information into symbol names. This is name mangling.

中文: C++ 支持函数重载、命名空间以及更复杂的类型信息,所以它会把额外信息编码进符号名,这就是名字重整

English: C does not need that, so C symbols are simple and unmangled.

中文: C 不需要这些机制,所以 C 的符号名通常是简单直接的、不会重整。


3 extern "C" 不能做什么

English: extern "C" does not magically make C code legal in a C++ file. It only changes linkage.

中文: extern "C" 不会让 C 代码在 C++ 文件里"自动合法",它只改变链接方式。

English: It also does not make two different function signatures compatible. The parameter types and return type still must match.

中文: 它也不会让两个不同函数签名变成兼容。参数类型和返回值类型仍然必须匹配。

extern "C"标准写法

头文件写法 / Header pattern

test.h

cpp 复制代码
#ifdef __cplusplus
extern "C"{
#endif

#include <stdio.h>



void show();

#ifdef __cplusplus
}
#endif

English: This is the standard mixed C/C++ header pattern.

中文: 这是标准的 C/C++ 混合头文件写法。

English: If the header is included by C++ code, show gets C linkage. If it is included by C code, the extern "C" part is ignored because __cplusplus is not defined.

中文: 如果这个头文件被 C++ 代码包含,show 就会获得 C 链接;如果被 C 代码包含,因为 __cplusplus 没定义,extern "C" 那部分就会被跳过。

main.cpp

cpp 复制代码
#include <iostream>
#include "test.h"


void test01()
{
    show();
}

int main()
{
    test01();

    return EXIT_SUCCESS;
}

test.c

cpp 复制代码
#include "test.h"

void show()
{
    printf("hello world.\n");
}
bash 复制代码
shaoyoulu@shaoyoulu:~/Code/extern$ g++ -c main.cpp -o main.o
shaoyoulu@shaoyoulu:~/Code/extern$ gcc -c test.c -o test.o
shaoyoulu@shaoyoulu:~/Code/extern$ g++ main.o test.o -o main
shaoyoulu@shaoyoulu:~/Code/part1/extern$ ./main 
hello world.
shaoyoulu@shaoyoulu:~/Code/extern$ 

extern "C" 出现在声明端还是定义端

English: In mixed-language projects, the most common practice is to put extern "C" in the header declaration, so both C and C++ translation units stay consistent.

中文: 在混合语言工程中,最常见的做法是把 extern "C" 放在头文件声明处,这样 C 和 C++ 的翻译单元都能保持一致。

English: If both declaration and definition are compiled as C++, then both sides must agree on C linkage if you want a C symbol.

中文: 如果声明和定义都按 C++ 编译,那么两边都必须约定使用 C 链接,否则不会得到 C 符号。

extern "C" 和重载

English: Functions declared with extern "C" cannot be overloaded, because C linkage does not carry type information for overload resolution.

中文: 被声明为 extern "C" 的函数不能重载,因为 C 链接不携带用于重载解析的类型信息。

English: This is another important reason why extern "C" is only for interface boundaries.

中文: 这也是为什么 extern "C" 主要用于接口边界,而不是随便在内部代码里乱用。

纯 C++,不需要 extern "C"

English: Show that compiling everything with g++ makes the program work because everything is C++.

中文: 先展示"全部用 g++ 编译"时程序能工作,因为整个程序都被当成 C++。

真正的 C + C++ 混编,必须用 extern "C"

English: Then show g++ main.cpp + gcc test.c, and let it fail without extern "C".

中文: 然后展示 g++ main.cpp + gcc test.c,在没有 extern "C" 时失败。

加上 extern "C" 后成功

English: Finally, add the extern "C" guard in the header or declaration, and show the link succeeds.

中文: 最后加上头文件里的 extern "C" 保护,展示链接成功。

Misconceptions

English: Misconception 1: .c files are always compiled as C.

中文: 误区 1:.c 文件总是按 C 编译。

English: Correction: the compiler determines the language mode. g++ will compile .c files as C++.

中文: 更正:语言模式由编译器决定。g++ 会把 .c 文件按 C++ 编译。


English: Misconception 2: extern "C" changes runtime calling behavior.

中文: 误区 2:extern "C" 会改变运行时调用行为。

English: Correction: it mainly changes symbol linkage and mangling, not the high-level function logic.

中文: 更正:它主要改变的是符号链接和名字重整,不改变函数逻辑本身。


English: Misconception 3: Once extern "C" is added, any C and C++ code can freely mix.

中文: 误区 3:加了 extern "C" 后,C 和 C++ 就能随便混用。

English: Correction: types, headers, memory management, and API conventions still must be compatible.

中文: 更正:类型、头文件、内存管理、API 约定仍然必须兼容。

相关推荐
乐观勇敢坚强的老彭2 小时前
C++信奥静态数组和动态数组
数据结构·c++·算法
gumichef2 小时前
第一章:面向对象核心——类和对象深度讲解
开发语言·c++
郝学胜-神的一滴3 小时前
[简化版 GAMES 104] 现代游戏引擎 04:从0到1构建你的游戏世界
c++·游戏·unity·游戏引擎·软件工程·unreal engine
月光船幽幽3 小时前
呼吸孔设计重塑系统稳定性
python·科技·算法
Bryce学亮3 小时前
FileLine,基于 Qt 6 + QML 构建的跨平台文件传输与即时通讯工具
数据库·c++·人工智能·python·qt·github
旖旎夜光3 小时前
LeetCode 991: 坏了的计算器(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
旖旎夜光3 小时前
LeetCode 553:最优除法(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
雾喔3 小时前
算法练习7
java·数据结构·算法
过期的秋刀鱼!3 小时前
重点-偏差方差与神经网络
人工智能·深度学习·神经网络·算法·机器学习·过拟合·l2正则化