[C/C++知识点] C++调用C语言之extern "C"

2021-03-27 00:27

阅读:487

标签:com   说明   ios   很多   总结   return   main   有用   代码块   

一、引言
      extern "C"{};的作用就是为了实现C++代码调用其他C语言代码。加上extern "C"后,会告知编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数时,会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;但C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
      这个功能十分有用,因为在C++出现以前,很多代码都是C语言写的,而且很底层的库也是C语言写的,为了更好的支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略。

二、举例
一共3个文件,分别是用C语言实现的加法运算函数cPlus.h和cPlus.c,以及用C++实现的主函数main.cpp

// cPlus.h
int addC(int x, int y);
// cPlus.c
#include "stdio.h"
int addC(int x, int y)
{
    return x + y;
}

主函数:

// main.cpp
#include "cPlus.h"
#include "iostream"
using namespace std;

int main()
{
    cout 2, 3)  endl;
    return 0;
}

可以看到主函数main是用C++实现的,并且在主函数中调用了用C语言实现的加法函数addC。
接下来进行编译,报错了,报错信息如下,无法解析符号addC(int, int):

技术图片

重新改写cPlus.h文件如下:

// cPlus.h
#ifdef __cplusplus
extern "C" {
#endif

    int addC(int x, int y);

#ifdef __cplusplus    
};
#endif

再次对main函数进行编译,发现编译成功。

三、分析
       为什么对C代码块增加了extern "C"{};之后,编译就不会报错了?这还是得从C语言和C++本身说起。
       C和C++编译器对变量或函数的编译处理是不完全相同的。C++支持重载,编译后的函数一般是以下划线+函数名+形参类型来命名的;C语言不支持重载,编译后的变量或函数一般以下划线+函数名来命名的。

       如函数void fun(int,int),C++编译后的可能是_fun_int_int(不同编译器可能不同);而C语言编译后可能是_fun。
       因此,main函数里用C++对addC进行编译得到_addC_int_int的函数名,而C代码里自身对addC进行编译得到的是_addC的函数名,这就会造成在链接过程中C++在符号库里会找不到_addC_int_int这个符号表。但是在C代码里用extern "C"进行说明后,用C++对addC进行编译时,会按照C语言格式进行编译,生成_addC函数名。
      打开一个C语言的标准头文件如stdio.h后,可以发现,都是有类似的结构:

// stdio.h

#ifndef _INC_STDIO
#define _INC_STDIO

#ifdef __cplusplus
extern "C" {
#endif

    code...
    
#ifdef __cplusplus
}
#endif

四、使用场景
1、C++代码调用C语言代码。
2、在C++的头文件中使用。
3、在多个人协同开发时,有的人擅长C语言,有的人擅长C++,这种情况下也会用到。

五、用法总结
1、可以单一语句使用

extern "C" int addC(int, int);

2、可以复合语句使用

extern "C" {
    int addC(int, int);
}

3、可以包含头文件,相当于头文件中的声明都加了extern "C"

extern "C" {
    #include "stdio.h"
    int addC(int, int);
}

4、不可以将extern "C"添加在函数内部,例如下面的用法是错的

int addC(int x, int y)
{
    extern "C" {
        return x + y;
    }
}

六、注意
1、extern "C"用来指明,这段代码按照C语言方式进行编译。
2、extern "C"是用来修饰C代码的,使用目标是C代码,不存在在C++代码里使用。
3、extern本身也是C语言的一个关键字,其修饰的变量或函数可以在本模块或其它模块中使用,因此extern "C"修饰的变量或函数具有和extern相同的生命周期。
4、由于static和extern的作用正好相反,因此用static修饰的函数或变量不能被extern "C"修饰。
5、extern "C"一般配合着__cplusplus使用。__cplusplus是告诉编译器,如果定义了__cplusplus,即如果是cpp文件,因为cpp文件都是默认会定义这个宏的。

[C/C++知识点] C++调用C语言之extern "C"

标签:com   说明   ios   很多   总结   return   main   有用   代码块   

原文地址:https://www.cnblogs.com/programmer-home/p/13672429.html


评论


亲,登录后才可以留言!