友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

VC语言6.0程序设计从入门到精通-第99章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




定和_fastcall 调用约定。  

   _stdcall 调用约定相当于 16 位动态库中经常使用的 PASCAL 调用约定。在 32 位的 Visual  

C++  6。0 中 PASCAL  调用约定不再被支持(实际上它已被定义为_stdcall 。除了_pascal  外, 

_fortran 和_syscall  也不被支持),取而代之的是_stdcall 调用约定。两者实质上是一致的,即 

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

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

                                        

   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                             编译, 



 ·262 ·  


…………………………………………………………Page 274……………………………………………………………

                                                                  第 10 章    动态链接库  



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

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

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

也是一个“@ ”符号和其参数的字节数,格式为@functionname@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 调用约定规则如下。  

    o  以“? ”标识函数名的开始,后跟函数名。  

    o  函数名后面以“@@YG”标识参数表的开始,后跟参数表。  

    o  参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型。  

    o  参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z ”标识结束。 

      其格式为“?functionname@@YG*****@Z ”或“?functionname@@YG*XZ ”,例如: 

      int  Test1(char  *var1;unsigned  long)………… “?Test1@@YGHPADK@Z ”,void  Test2()…………

      “?Test2@@YGXXZ ”。  

    cdecl 调用约定规则同上面的            stdcall 调用约定类似,只是参数表的开始标识由上面的 

“ 

 @@YG”变为“@@YA”。  

    fastcall 调用约定规则同上面的            stdcall 调用约定,只是参数表的开始标识由上面的 

 @@YG”变为“@@YI”。  

“ 



    3 .得到没有修饰的函数名  



    Visual  C++ 输 出 函 数 时 使 用 _declspec(dllexport)  , 而 不 再 用 _export    修 饰 字 。 

_declspec(dllexport)在 C 调用约定、C 编译情况下可以去掉输出函数名的下划线前缀。extern  

〃C〃使得在 C++ 中使用 C 编译方式成为可能,在一个 C++文件中,用 extern 〃C〃来指明该函数 

使用 C 编译方式。例如,在一个 C++文件中,有如下函数:  



    extern 〃C〃 {void    __declspec(dllexport) __cdecl Test(int var);}  



    其输出函数名为 Test 。  

    为了方便,可以使用下列预处理语句:  



    #if defined(__cplusplus)  



    extern 〃C〃  



     {  



    #endif  



        // 函数原型说明  



    #if defined(__cplusplus)  



                                                                              ·263 ·  


…………………………………………………………Page 275……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



    }  



    #endif  



    经过上面的特殊处理,不管在 C 中,还是在 C++ 中都可以得到一个无任何修饰的函数名。  

    如果不用_declspec(dllexport)修饰字输出函数,而用  DEF  文件来输出函数。将要输出的 

函数修饰名罗列在 EXPORTS 之下,这个名字必须与定义函数的名字完全一致,如此就得到 

一个没有任何修饰的函数名了。  



10。4。4    模块定义文件(DEF 文件)  



    模块定义文件(DEF )是一个或多个用于描述 DLL 属性的模块语句组成的文本文件,每 

个 DEF 文件至少必须包含以下模块定义语句。  

    o  第一个语句必须是 LIBRARY 语句,指出 DLL 的名字;  

    o  EXPORTS 语句列出被导出函数的名字 ;将要输出的函数修饰名罗列在 EXPORTS 下, 

      这个名字必须与定义函数的名字完全一致,如此就得到一个没有任何修饰的函数名。  

    o  可以使用 DEs criptION 语句描述 DLL 的用途(此句可选);  

    o  〃;〃对一行进行注释(可选 )。  



10。5    动态链接库中的资源  



    利用 Visual  C++工具能够创建基于 MFC 的常规/扩张动态链接库,这种形式的动态链接 

库可以方便地添加资源 。应用程序在调用 DLL 的时候可以很方便地使用其中的资源,这在很 

大程度上方便了应用程序的编写。为了使读者理解在动态链接库中使用资源的方法,本节将 

通过在动态链接库中添加对话框资源来介绍使用资源的具体过程。  



实例 10…1:动态链接库中使用资源实例。源代码在光盘中“10实例 10…1vcDlgDLL”目录下。  



    为了能够在动态链接库中方便地使用资源,可以先创建一个“MFC  AppWizard(dll) ”工 

程,如图 10…4 所示。然后选择“Regular Dll using shared MFC DLL ”项,单击“Finish ”按钮 

即可生成动态链接库。  



                                                       



                     
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!