当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

摸索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++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 摸索CORBA技术的操纵范围
  • 深度摸索C++对象模子(1)
  • 深度摸索C++对象模子(2)
  • 深度摸索C++对象模子(3)
  • 深度摸索C++对象模子(4)
  • <b>深度摸索C++对象模子(5)</b>
  • <b>深度摸索C++对象模子(6)</b>
  • 深度摸索C++对象模子(7)
  • 摸索C++的奥秘之详解extern "C"
  • 《深度摸索C++对象模子》读书笔记(1)
  • 《深度摸索C++对象模子》读书笔记(2)
  • <b>《深度摸索C++对象模子》读书笔记(3)</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .