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