1️⃣ 作用以及用途

  • extern "C" 的主要作用就是为了能够正确实现C++代码调用其他C语言代码。
  • 加上 extern "C" 后,会指示编译器这部分的代码按C语言,而不是C++的方式进行编译。

2️⃣ 底层理由

  • 由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名。
  • C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
  • 例如函数void fun(int, int)编译后的可能是 _fun_int_int—-不同编译器可能不同,但都采用了相似机制,用函数名和参数类型来命名编译后的函数名;
  • C语言没有类似的重载机制,一般是利用函数名来指明编译后的函数名的,对应上面的函数可能会是_fun这样的名字。

因此,如果不加 extern "c",在链接阶段,链接器会从 moduleA 生成的目标文件 moduleA.obj 中找 _fun_int_int 这样的符号,显然这是不可能找到的,因为 fun() 函数被编译成了_fun 的符号,因此会出现链接错误。

3️⃣ 代码示例

  • 模块A的头文件以及源文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #ifndef __MODULE_A_H 
    #define __MODULE_A_H

    int fun(int, int);

    #endif

    -----------------------------------------

    #include "moduleA"

    int fun(int a, int b)
    {
    return a+b;
    }
  • 模块B的头文件以及源文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #ifndef __MODULE_B_H 
    #define __MODULE_B_H

    #ifdef __cplusplus //这一部分就是告诉编译器,如果定义了__cplusplus(即如果是cpp文件----cpp文件默认定义了该宏),
    // 则采用C语言方式进行编译
    extern "C"{
    #include"moduleA.h"
    #endif
    ··· //其他代码

    #ifdef __cplusplus
    }
    #endif
    #endif

    -----------------------------------------

    #include"moduleB.h"

    int main()
    {
      cout<<fun(2,3)<<endl;
    }

原文链接:https://blog.csdn.net/qq_28087491/article/details/116595151