摸索C++的奥秘之详解extern "C"[VC/C++编程]
本文“摸索C++的奥秘之详解extern "C"[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
经常在cpp的代码之中看到这样的代码:
#ifdef __cplusplus
extern "C" {
#endif
//一段代码
#ifdef __cplusplus
}
#endif
这样的代码毕竟是什么意思呢?首先,__cplusplus是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:假如这是一段cpp的代码,那么加入extern "C"{和}处理此中的代码.
要懂得为什么利用extern "C",还得从cpp中对函数的重载处理开始说起.在c++中,为了支慎重载机制,在编译生成的汇编码中,要对函数的名字举行一些处理,加入比方函数的返回范例等等.而在C中,只是简单的函数名字罢了,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的.
比方下面的一段简单的函数,我们看看加入和不加入extern "C"产生的汇编代码都有哪些改变:
int f(void)
{
return 1;
}
在加入extern "C"的时刻产生的汇编代码是:
.file "test.cxx"
.text
.align 2
.globl _f
.def _f; .scl 2; .type 32; .endef
_f:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
但是不加入了extern "C"之后
.file "test.cxx"
.text
.align 2
.globl __Z1fv
.def __Z1fv; .scl 2; .type 32; .endef
__Z1fv:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
两段汇编代码一样都是利用gcc -S号令产生的,全部的地方都是一样的,唯独是产生的函数名,一个是_f,一个是__Z1fv.
懂得了加入与不加入extern "C"之后对函数名称产生的影响,我们持续我们的谈论:为什么需求利用extern "C"呢?C++之父在计划C++之时,考虑到当时已经存在了大量的C代码,为了支持本来的C代码和已经写好C库,需求在C++中尽大概的支持C,而extern "C"就是此中的一个战略.
试想这样的情形:一个库文件已经用C写好了并且运行得很杰出,这个时刻我们需求利用这个库文件,但是我们需求利用C++来写这个新的代码.假如这个代码利用的是C++的方法链接这个C库文件的话,那么就会呈现链接错误.我们来看一段代码:首先,我们利用C的处理方法来写一个函数,也就是说假定这个函数当时是用C写成的:
//f1.c
extern "C"
{
void f1()
{
return;
}
}
编译号令是:gcc -c f1.c -o f1.o 产生了一个叫f1.o的库文件.再写一段代码调用这个f1函数:
// test.cxx
//这个extern表示f1函数在别的地方定义,这样可以通过
//编译,但是链接的时刻还是需求
//链接上本来的库文件.
extern void f1();
int main()
{
f1();
return 0;
}
通过gcc -c test.cxx -o test.o 产生一个叫test.o的文件.然后,我们利用gcc test.o f1.o来链接两个文件,但是出错了,错误的提醒是:
test.o(.text + 0x1f):test.cxx: undefine reference to 'f1()'
也就是说,在编译test.cxx的时刻编译器是利用C++的方法来处理f1()函数的,但是实际上链接的库文件倒是用C的方法来处理函数的,所以就会呈现链接过不去的错误:因为链接器找不到函数.
因此,为了在C++代码中调用用C写成的库文件,就需求用extern "C"来奉告编译器:这是一个用C写成的库文件,请用C的方法来链接它们.
比方,目前我们有了一个C库文件,它的头文件是f.h,产生的lib文件是f.lib,那么我们假如要在C++中利用这个库文件,我们需求这样写:
extern "C"
{
#include "f.h"
}
回到上面的问题,假如要改正链接错误,我们需求这模样改写test.cxx:
extern "C"
{
extern void f1();
}
int main()
{
f1();
return 0;
}
重新编译并且链接便可以过去了.
总结
C和C++对函数的处理方法是差别的.extern "C"是使C++可以调用C写作的库文件的一个手段,假如要对编译器提醒利用C的方法来处理函数的话,那么就要利用extern "C"来阐明.
以上是“摸索C++的奥秘之详解extern "C"[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |