发信人: cnix (Apocalypse~~~~~), 信区: SoftwareTesting
标 题: Re: 求助,请大家帮忙给测试团队起个名字
发信站: 水木社区 (Tue Mar 18 18:46:54 2008), 站内
女娲
【 在 Emily3007 (tracy) 的大作中提到: 】
: hi
: 请大家帮忙给软件测试团队取个名字,体现出工作性质,又能反应出精神面貌,最好再有点典故或者神话色彩,呵呵
: 实在想不出合适的,请大家帮忙,谢谢!
3月 2008的归档发信人: cnix (Apocalypse~~~~~), 信区: SoftwareTesting 女娲
转载自http://blog.csdn.net/goodname008
Visual C/C++ 的编译器提供了几种函数调用约定,了解这些函数调用约定的含义及它们之间的区别可以帮助我们更好地调试程序。在这篇文章里,我就和大家共同探讨一些关于函数调用约定的内容。 Visual C/C++ 的编译器支持如下的函数调用约定:
上面这张表只简单地列出了每种函数调用约定的特点,既然这篇文章题目的前两个字是“剖析”,哪能这么容易就完事!?下面就对上面这四种函数调用约定逐个“剖析”: 一、__cdecl函数调用约定 这是C和C++ 程序默认的函数调用约定,参数按从右到左的顺序压入堆栈,由调用函数负责清理堆栈,把参数弹出栈。也正是因为用来传送参数的堆栈是由调用函数维护的,所以实现可变参数的函数只能使用这种函数调用约定。因为每一个调用它的函数都要包含清理堆栈的代码,所以编译后的可执行文件的大小要比调用__stdcall函数的大。使用这种函数调用约定时,修饰后的函数名只是在原函数名前加上了一个_(下划线),并且不改变函数的大小写。对于__cdecl,我们一般不特别指出,因为它是C和C++ 程序默认的函数调用约定,所以只有将编译选项设置成/Gz(stdcall)或/Gr(fastcall)时,我们才有必要在函数名前显式地指出采用这种函数调用约定。下面举一个例子:
函数体及调用语句如上所示,修饰后的函数名为_Sumcdecl,堆栈和寄存器状态如下(一行表示4个字节):
口说无凭,代码能说明一切,下面的程序乃Win32 console application(.exe)是也:
在我的机器上,运行结果如下:
函数声明部分的extern “C”表示连接规范(Linkage Specification)采用C,而不是C++,不加extern “C”的情况我会在后面统一讨论。__declspec(dllexport)表示将该函数导出,将生成.lib文件,以便我们验证函数名是怎样修饰的。关于修饰后的函数名,我们可以使用VC98\bin目录下的dumpbin工具来验证: dumpbin /exports 文件名> 输出结果如下:
二、__stdcall函数调用约定 __stdcall函数调用约定通常用于Win32 API函数,参数按从右到左的顺序压入堆栈,由被调用函数负责清理堆栈,把参数弹出栈。在windows.h中包含了windef.h,而windef.h中定义了一个WINAPI宏:#define WINAPI __stdcall,呵呵,应该心知肚明了。使用这种函数调用约定时,修饰后的函数名在原函数名前加上了一个_(下划线),并且在原函数名后加上“@数字”,当然也不改变函数的大小写,@ 后面的数字表示参数所占的字节数,这里有一点要注意的,不足32位(4字节)的参数将在参数传递时被扩充到32位。下面举一个例子:
函数体及调用语句如上所示,修饰后的函数名为_Sumstdcall@12,int是32位的,占4个字节,3个32位的变量,共12个字节。堆栈和寄存器状态如下(一行表示4个字节):
仍然以代码说明:
|