C++调用C接口必须要加extern "C"的原因

1、第一层直接原因,如果不加extern "C",C++程序调用C接口会出现如下错误(链接时)

undefined reference

以实例演示:
1)错误示例
在ss.c中有如下代码

#include <stdio.h>

void cfun_output(int x)
{
    printf("%d
", x);
}

在ss.h头文件中有如下定义

#ifndef SS_H_
#define SS_H_

void cfun_output(int x);
    
#endif // SS_H_

在tt.cpp中调用ss.h中定义的C接口

#include <iostream>

#include "ss.h"

int main()
{
    cfun_output(5);
    
    return 0;
}

依次执行以下命令

$ gcc -c ss.c -o ss.o // 只编译成目标文件,不链接
$ g++ -c tt.cpp -o tt.o // 只编译不链接
$ g++ -o tt tt.o ss.o // 链接生成目标程

出现如下错误提示
tt.o: In function `main':
tt.cpp:(.text+0x11): undefined reference to `cfun_output(int)'
collect2: error: ld returned 1 exit status

2)错误纠正
只修改ss.h为如下

#ifndef SS_H_
#define SS_H_

#ifdef __cplusplus
extern "C" {
#endif

void cfun_output(int x);

#ifdef __cplusplus
}
#endif
    
#endif // SS_H_

重新执行以下命令

$ gcc -c ss.c -o ss.o // 只编译成目标文件,不链接
$ g++ -c tt.cpp -o tt.o // 只编译不链接
$ g++ -o tt tt.o ss.o // 链接生成目标程序

运行得出结果为:5

2、根本原因分析
C++支持函数重载,C语言不支持函数重载。C++程序编译后在库中的名字与C语言编译后在库中的名字不同。
假设某个函数原型为

void foo(int x, int y)

该函数被C编译器编译后在库中的名字为_foo,而被C++编译器编译后在库中生成的名字类似于_foo_int_int
C++提供了C连接交换指定符号 extern "C" 用于解决名字的匹配问题。

3、使用方法

在被C++调用的C头文件中,将C接口包含于以下定义中

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif
原文地址:https://www.cnblogs.com/aqing1987/p/4185268.html