帶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
因?yàn)閙ain.cpp采用C++方式編譯雹熬,所以相當(dāng)于定義了宏__cplusplus谣膳。而main.cpp中包含了add.h,所以extern "C" {}中的函數(shù)都采用C的編譯方式仰楚。
所以兩個(gè)目標(biāo)文件中的符號(hào)名相同犬庇。
不帶extern "C"的效果
將add.h中extern "C"相關(guān)的語句注釋掉
//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
因?yàn)閙ian.cpp用C++編譯臭挽,所以編譯出來的目標(biāo)文件中,add的符號(hào)名為__Z3addii葬荷,后面多了ii纽帖,表示add函數(shù)有兩個(gè)int型的參數(shù)。
而add.c用C編譯扒吁,add的符號(hào)名為_add室囊。
因?yàn)閮蓚€(gè)目標(biāo)文件中的符號(hào)名不同,所以在最后鏈接時(shí)會(huì)出現(xiàn)錯(cuò)誤盼铁。
結(jié)論
- 用C寫代碼饶火,為了C++可以調(diào)用,都會(huì)加上
#ifdef __cplusplus
extern "C" {
#endif
......
#ifdef __cplusplus
}
#endif
- C++調(diào)用沒有extern "C"的C代碼
extern "C" {
#include "add.h" //extern "C" {}包含頭文件方式
}
extern "C" {
int add(int a, int b); //extern "C" {}包含調(diào)用函數(shù)方式
}