月无踪 月无踪
人生就如心电图,一帆风顺说明你挂了。
关注数: 45 粉丝数: 207 发帖数: 8,876 关注贴吧数: 34
[Windows API]函数调用约定 1.4.1 __cdecl、_cdecl、cdecl关键字 这是在C++ Builder中特有的关键字,__cdecl、_cdecl、cdecl可以用来修饰变量或者函数,其含义是指定的变量或者函数使用C语言的调用规则和命名规则。在C++ Builder中C调用规则是缺省的设置,可以通过Project的Option菜单在Advanced Compiler标签中来改变缺省设置。 对于C命名规则的变量或函数,具有大小些敏感、编译后变量名称前下划线前导符,这与Pascal语言是不一样的。对于函数,C调用规则要求使用堆栈传递参数,参数传递的顺序为自右向左依次压入堆栈,由调用者自行清除堆栈,C调用规则允许向函数传递不定参数,但这种调用方式系统需要更多的开销来完成参数的匹配,除非特殊用途一般尽量不要使用,这种调用方式最典型的例子是控制台程序中的main函数,程序运行时可以不带参数,也可以带多个参数。 在一个独立的程序中,采用那种调用规则或者命名规则影响并不十分大,但是在多种语言混合编程,或者编写带有数据输出或函数输出的可执行模块(可执行文件和动态链接库)时,命名规则和调用规则显得尤为重要,使用不当则可能导致程序无法正常运行,甚至使系统崩溃。 __cdecl、_cdecl、cdecl的使用语法如下: cdecl <data/function definition> ; _cdecl <data/function definition> ; __cdecl <data/function definition> ; 例如: int cdecl I; //编译后标识符为“_I” void __cdecl Fun(); //编译后函数名为“_Fun” 1.4.2 __fastcall、_fastcall关键字 __fastcall和_fastcall也是C++ Builder中特有的关键字,只能用于修饰函数,其作用是指定函数使用“寄存器”调用规则,使用语法如下: return-type _fastcall function-name(parm-list) return-type __fastcall function-name(parm-list) 例如: void __fastcall GetName(int Index); 使用“寄存器”调用规则的函数,其参数传递顺序为自左向右依次传递,并且将前三个参数尽可能的使用EAX、EBX、ECX这三个寄存器传递,对于前三个参数中浮点类型、结构类型等超过四个字节的变量,和第四个及以后的参数则采用堆栈来传递,因此采用“寄存器”调用规则的函数只能传递固定数量的参数。 在C++ Builder中,所有属于VCL的成员函数,必须是__fastcall类型,编译器将“寄存器”调用规则和C调用规则、Pascal调用规则以及Win32的标准等其它调用规则是同等对待的,因此__fastcall关键字不能和__cdecl、__pascal、__stdcall等关键字联合使用,也不能和__export关键字同时使用(实际上使用__fastcall规则的函数是允许输出的,只是这种调用规则编写的dll或可执行模块只能被C++ Builder或者Delphi开发的程序载入并调用输出的函数)。 被指定为“寄存器”调用的函数会在编译时被冠以前导符@,这将使得C及C++的函数命名过于混乱,但是这种调用规则有很高的执行效率,因此在C++ Builder中几乎所有VCL的成员函数都使用这种调用规则。 但是__fastcall和_fastcall是C++ Builder之前的C++编译器所没有的调用规则,为了保证兼容性,可以使程序连接以前版本的编译器生成的库文件,C++ Builder提供了-VC命令行选项,缺省状态下,该选项是关闭的,当需要时,可以通过命令行编译并选择-VC选项。 1.4.3 __msfastcall、__msreturn关键字 __msfastcall和__msreturn也是C++ Builder中特有的关键字,使用这两个关键字可以为程序提供和Microsoft兼容的“寄存器调用”规则以及和Microsoft兼容的函数返回的规则。 被__msfastcall修饰的函数,其参数传递顺序为前两个参数如果长度小于4字节,则分别使用ECX和EDX寄存器传递,其余的参数和前两个不能使用寄存器传递的参数则按照从右向左的顺序通过堆栈来传递,堆栈由被调用函数负责清除。
首页 4 5 6 7 8 9 下一页