extern “C“用法简介


1 extern "C"作用

      extern "C"是C++特有的指令(C无法使用该指令),目的在于支持C++与C混合编程。
      extern “C”的作用是告诉C++编译器(如g++)用C规则编译指定的代码

除函数重载外,extern "C"不影响C++其他特性;


2 为什么要指定C规则来编译代码呢?

      这是因为C和C++的编译规则不一样,主要区别体现在编译期间生成函数符号的规则不一致。请看如下范例:

/*------------------func1.h头文件------------------*/
#include <stdio.h>
void func1(); //declare
/*-----------------func1.c C源码文件----------------*/
#include "func1.h"
void func1()
{
    printf("Hello world!\n");
}
/*--------------main.cpp C++源码文件-------------*/
#include "func1.h"
int main()
{
  func1();
  return 0;
 }

//采用gcc进行编译,将报错!但是采用g++编译却正常;细看错误详情可知,是main()函数内找不到func1()函数报错,即编译阶段没报错,是链接的阶段报错了!

gcc main.cpp func1.c -o hello //gcc编译报错,错误如下图所示

gcc编译报错

g++ main.cpp func1.c -o hello //g++编译正常

2.1 原因分析

      C++支持函数重载,而C不支持。正是因为C++需要支持重载,因此单纯的函数名已无法区分出具体调用的函数,因此在编译阶段就需要将形参列表作为附加项增加到函数符号中。
      func1.c文件中的func1()函数分别在C、C++对应的汇编码结果如下:

  • func1.c gcc汇编代码func1.sgcc -S func1.c
    gcc汇编代码
  • func1.c g++汇编代码func1.sg++ -S func1.c
    g++汇编代码
  • func1.c gcc生成的目标代码func1.ogcc -c func1.c
    gcc汇编结果
  • func1.c g++生成的目标代码func1.ogcc -c func1.c
    g++汇编结果
          对比上述2图可知,gcc与g++的区别仅在于func1()函数编译后对应的符号不同。C++编出来的函数符号明显比C的多出了一些信息(如__Z5),这里多出来的后缀信息就是形参列表的参数类型信息。
  • C:_func1
  • C++:__Z5func1v

原因:这是因为gcc会根据源文件的尾缀(.c、.cpp等)利用相应的代码规则进行编译,如.c(采用C规则),.cpp(采用C++规则);但g++对于.c、.cpp等文件一律采用C++规则进行编译,故不报错!详见gcc与g++区别

2.2 解决办法

      extern "C"的作用就是告诉C++编译器,将指定的函数用C规则编译:

  • 方法1:仅修改cpp文件而不修改.h文件,适用于函数较少情况!

该方法下,cpp文件不能再include func1()所在的头文件,如本例中的#include “func1.h” 需要被注释掉!!

/*--------------main.cpp C++源码文件-------------*/
//#include "func1.h"   /*该include语句需被注释掉*/
extern "C" void func1();
int main()
{
  func1();
  return 0;
}
  • 方法2:修改.c文件对应的.h文件,无需修改cpp文件(**推荐!**
/*------------------func1.h头文件------------------*/
#ifdef __cplusplus//两个下划线_
extern "C"{
#endif//!__cplusplus
 
#include <stdio.h>
    void func1();
    
#ifdef __cplusplus//两个__下划线
}
#endif//!__cplusplus

3 总结

  • 当C++程序需要调用自定义C库时,务必注意对C库的头文件进行extern "C"拓展,以免出现链接错误!
  • 当C++程序中采用的是C源文件(.c文件)时,统一使用g++编译,可以避免缺省extern "C"带来的链接错误问题!但建议还是对C文件进行extern "C"兼容!
  • 9
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值