带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 <stdio.h>
#include <stdlib.h>
#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" {}包含调用函数方式
}
网友评论