什么情况下需要加extern "C",通俗易懂

本文详细解析了C与C++在编译及链接过程中的差异,特别是在使用不同编译器时如何通过extern C来解决函数查找问题。通过示例代码展示了正确的实践方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下午看了一些关于extern "C"的博客,都写得很啰嗦,看来看去还是有一些细节不怎么了解,自己开了个程序测试了一下,总结了什么情况下需要加入extern “C”

首先c++和c语言编译器在将cpp编译成.o文件的时候对函数的编译方式是不一样的
例如函数void foo(int)
c++编译器会编译成_int_foo
c语言编译器会编译成_foo()

同样c++和c语言在链接的时候查找规则也是不一样的
还是以void foo(int)为例
c++会使用_int_foo去.o文件中查找
c会使用_foo()去查找

这样问题就来了。如果你在c++链接器下调用使用c编译器的文件(比如dll)那系统会提示找不到函数
反过来也找不到函数。
为了解决这个问题就引入了extern "C",
extern "C" 就是提示编译器(确切的说是提示C++的编译器)使用C语言的方式进行编译或者链接
所以为了确保使用不同编译器编译出来的代码出现找不到函数的情况,在c++编译器下需要在c代码的声明和定义中都加入extern "C"
同时C++在调用这些C函数的时候也应该加入extern "C"(或者引入带extern "C"的头)
代码如下:

//foo.h
#ifndef FOO_H
#define FOO_H
#ifdef __cplusplus
extern "C"{  //所有在大括号中的函数都会自动加上extern "C"    
#endif
 void foo(int);
 void foo1(char);
 //...other function
#ifdef __cplusplus
}
#endif
#endif//FOO_H


//foo.cc

/*包含了foo.h编译的时候就会自动使用c风格了,如果你不想包含foo.h的话,那还有另外两种办法
*1.像头文件一样把所有函数定义包含在extern "C"{....}中
*2.在每个函数定义前加上 extern "C" 如:extern "C" void foo(int){....}
*上面两种方法都需要判断是否c++编译器,因为在c编译器中使用extern "C"会报错,这里只是帮助理解而已,还是包含头文件吧。
*/
#include "foo.h"
void foo(int){
    //...do something
}

void foo1(char){
    //...do something
}

//main.cc
#include "foo.h"
int main(int argc, char* argv[]){
    foo(1);        //根据foo.h的声明采用c风格方式查找
    return 0;
}
使用c++编译器(__cplusplus已定义)
g++ -o main  main.cc foo.cc
使用c语言编译器
gcc -o main  main.cc foo.cc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值