字体
第(3/4)页
关灯
   存书签 书架管理 返回目录
两者实质上是一致的,即

    函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的

    是函数名的修饰部分(具体参见下一节介绍)。

    C 调用约定(即用_cdecl 关键字说明)和_stdcall 调用约定有所不同,虽然在参数传送方

    面是一样的,但C 调用约定对于传送参数的内存栈却是由调用者来维护的(也正因为如此,

    实现可变参数的函数只能使用该调用约定),另外,在函数名修饰约定方面也有所不同。

    _fastcall 调用约定的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用

    ECX 和EDX 传送前两个双字或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的

    函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。

    关键字_stdcall、_cdecl 和_fastcall 可以直接加在要输出的函数前,也可以在编译环境中选

    择“Setting...|C/C++|Code Generation”菜单命令,在如图10-3 所示的对话框中设置编译环境。

    当加在输出函数前的关键字与编译环境中的选择不同时,直接加在输出函数前的关键字有效。

    它们对应的命令行参数分别为/Gz、/Gd 和/Gr。默认状态为/Gd,即_cdecl。

    图10-3 编译环境设置

    如果要完全模仿PASCAL 调用约定首先必须使用_stdcall 调用约定,至于函数名修饰约

    定,可以通过其他方法模仿。另外需要注意的是Windows.h 支持WINAPI 宏,该宏可以将输

    出函数翻译成适当的调用约定,在WIN32 中,它被定义为_stdcall。

    2.函数名修饰约定

    函数名修饰约定随编译种类和调用约定的不同而不同,下面分别说明。对于C 编译,

    枫叶文学网www.fywxw.com

    第10 章 动态链接库

    ·263·

    _stdcall 调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的

    字节数,格式为_functionncom@number。_cdecl 调用约定仅在输出函数名前加上一个下划线

    前缀,格式为_functionncom。_fastcall 调用约定在输出函数名前加上一个“@”符号,后面

    也是一个“@”符号和其参数的字节数,格式为@functionncom@number。它们均不改变输出

    函数名中字符的大小写,这和PASCAL 调用约定不同,PASCAL 约定输出的函数名无任何修

    饰且全部大写。本例将给出一种完全模仿PASCAL 调用约定的方法,在DEF 文件的EXPORTS

    段通过别名来实现。例如:

    int __stdcall MyFunc (int a,double b);

    void __stdcall InitCode (void);

    在DEF 文件中:

    EXPORTS

    MYFUNC=_MyFunc@12

    INITCODE=_InitCode@0

    Visual C++编译输出的函数名修饰较为复杂,编译时stdcall 调用
上一页 目录 下一页