分类: C/C++
2010-10-16 09:57:55
1. 函数名修饰
C的编译器、C++的编译器对代码中的函数名修饰各不同,以int func(int, int)为例,C的编译器会将函数名改编为_func, 而C++的编译器为了支持函数重载机制,会改编为_func_int_int 或_funcii之类的名字(各编译器不同)。
还要注意堆栈调用方式:__cdecl、__stdcall 、__fastcall 对函数名修饰的影响。
如果这个函数是在C中编译成库,库文件中的函数名为_func;同一个函数名但C++中编译时,改编为_func_int_int 或_funcii,这样C++链接器以_func_int_int 或_funcii去库目标文件中链接,结果是找不到的,出错。
2. extern "C"链接指示符
为了防止出现这种尴尬,在C++调用时,将在函数声明前加个extern "C" ,告诉C++的编译器,不要对代码中该函数名进行C++命名方式改编,而是使用C的函数名风格命名,这样,链接器用该函数名来查找C库中的函数时,才能找到匹配的链接点。
extern "C"链接指示符只能在C++语言文件中使用,而C语言中是不支持extern "C"声明,在 . c文件中包含extern "C"时会出现编译语法错误。
通常C中编写的函数如果有在其它语言中使用的可能,通常会有下面形式的声明:
#ifdef __cplusplus
extern "C" {
#endif
/**** some declaration
or so *****/
#ifdef __cplusplus
}
#endif /* end of __cplusplus */
说明://///__cplusplus是C++编译器的自定义宏,当使用C++编译器编译这段 代码时,__cplusplus就是已定义了;而当使用的是C编译器,则__cplusplus还未定义。
3. extern "C" 的使用要点
(1)可以是单一语句
extern "C" double sqrt(double);
(2)可以是复合语句, 相当于复合语句中的声明都加了extern "C"
extern "C"
{
double sqrt(double);
int min(int, int);
}
(3)可以包含头文件,相当于头文件中的声明都加了extern "C"
extern "C"
{
#include
}
(5)如果函数有多个声明,可以都加extern "C", 也可以只出现在第一次声明中,后面的声明会接受第一个链接指示符的规则。
(6)除extern "C", 还有extern "FORTRAN" 等。