extern "C"

带extern "C"的效果

//add.h
#ifndef ADD_H
#define ADD_H

#ifdef __cplusplus
extern "C" {
#endif

int add(int a, int b);

#ifdef __cplusplus
}
#endif
#endif
//add.c
#include "add.h"

int add(int a, int b)
{
    return (a + b);
}
//main.cpp
#include 
#include 
#include "add.h"

int main(int argc, char **argv)
{
     int a = atoi(argv[1]);
     int b = atoi(argv[2]);
     printf("result=%d\n", add(a, b));
     return 0;
}

$gcc -c add.c -o add.o
$nm add.o

0000000000000000 T _add

$gcc -c main.cpp -o main.o
$nm main.o

                 U _add
                 U _atoi
0000000000000000 T _main
                 U _printf     

因为main.cpp采用C++方式编译,所以相当于定义了宏__cplusplus。而main.cpp中包含了add.h,所以extern "C" {}中的函数都采用C的编译方式。
所以两个目标文件中的符号名相同。

不带extern "C"的效果

将add.h中extern "C"相关的语句注释掉

//add.h
#ifndef ADD_H
#define ADD_H

//#ifdef __cplusplus
//extern "C" {
//#endif

int add(int a, int b);

//#ifdef __cplusplus
//}
//#endif
#endif

$gcc -c add.c -o add.o
$nm add.o

0000000000000000 T _add

$gcc -c main.cpp -o main.o
$nm main.o

                 U __Z3addii
                 U _atoi
0000000000000000 T _main
                 U _printf

因为mian.cpp用C++编译,所以编译出来的目标文件中,add的符号名为__Z3addii,后面多了ii,表示add函数有两个int型的参数。
而add.c用C编译,add的符号名为_add。
因为两个目标文件中的符号名不同,所以在最后链接时会出现错误。

结论

  • 用C写代码,为了C++可以调用,都会加上
#ifdef __cplusplus
extern "C" {
#endif

......

#ifdef __cplusplus
}
#endif
  • C++调用没有extern "C"的C代码
extern "C" {
#include "add.h" //extern "C" {}包含头文件方式
}
extern "C" {
int add(int a, int b); //extern "C" {}包含调用函数方式
}

你可能感兴趣的:(extern "C")