( ´◔ ‸◔`) 来整理一下,部分内容来自网络。
首先 请回顾《程序员的自我修养》关于符号那一部分,大概是111页
什么是符号呢?符号是链接的接口,链接过程目标文件之间相互拼合实际上就是目标文件对地址的引用,即对函数和变量的地址的引用。
链接中,将函数和变量称为符号,对变量和函数而言符号值是他们的地址。
编译器为了支持C++语言的复特性(重载),采用了符号修饰或符号改编的机制。所以呢在将C++源代码编译成目标文件时,会将函数和变量的名字进行修饰形成符号名,不同编译器可能有不同的修饰方法,所以这里略。
C++编译器将extern “C”{ }大括号内的代码当作C语言代码处理,它使C++名称修饰机制不起作用。
=。=先来看个错误的栗子
/*fun.h*/
void fun();
/*a.c*/
#include "fun.h" #include <stdio.h> void fun() { printf("aloha~\n"); }
/*b.cpp*/
#include "fun.h" int main() { fun(); return 0; }
编译结果肯定是通不过的
error LNK2019: 无法解析的外部符号 "void __cdecl fun(void)" (?fun@@YAXXZ),该符号在函数 _main 中被引用
1>D:\!!!!\!!\项目\例题\Debug\例题.exe : fatal error LNK1120: 1 个无法解析的外部命令
C语言不支持extern “C”的语法,所以呢为了使C和C++兼容,使用C++的宏“__cplusplus”,C++编译器会在编译C++程序时默认定义这个宏。
一个比较经典的栗子如下:
#ifdef __cplusplus extern "C"{ #endif void fun(); #ifdef __cplusplus } #endif
在这个栗子中,若当前是C++的代码,那么fun会在exten “C”里被声明,若是C代码就直接声明。
所以,只要对fun.h文件中的代码做如上的修改就可以通过了,修改后的fun.h如下
#ifdef __cplusplus extern "C"{ #endif void fun(); #ifdef __cplusplus } #endif
---------------------------------------------------------------------------------------------------------
接下来的部分来自伟大的度娘๑乛◡乛๑ 百度百科里关于extern这块的详解
extern “C”表示被它修饰的目标是extern的,也是“C”的。extern是C/C++中表名函数和全局变量作用范围可见的关键字,它声明的函数和变量可以在本模块或其他模块中使用。
extern int a;只是声明!
面试题:
在C++中调用C代码有3中方式:
①修改C的头文件,如上述。
②在C++中重新声明C函数,在重新声明时添加extern “C”
#include "C" void fun();
③在包含C头文件的部分,添加extern “C”
extern "C"
{
#include "fun.h"
}