CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

弱问:int WINAPI WinMain是什么意思

楼主danvy_chan()2006-08-06 15:44:59 在 VC/MFC / 基础类 提问

以前只学过编控制台的程序,main函数的写法是  
   
  int   main或者void   main等等  
   
  这句int   WINAPI   WinMain里的WINAPI是什么意思?  
   
  谢谢!! 问题点数:10、回复次数:8Top

1 楼mscf(扎西特勒)回复于 2006-08-06 15:49:32 得分 10

WINAPI是个宏,一般代表_stdcall调用约定  
   
  WINAPI   Use   in   place   of   FAR   PASCAL   in   API   declarations.   If   you   are   writing   a   DLL   with   exported   API   entry   points,   you   can   use   this   for   your   own   APIs.Top

2 楼danvy_chan()回复于 2006-08-06 15:56:29 得分 0

仍然不理解:(  
   
  按照以前学的知识,函数格式是:  
  [返回类型]   [函数名](参数表){函数体}  
   
  我想这里int就是返回类型,winmain是函数名,那么winapi是什么呢?  
  Top

3 楼mscf(扎西特勒)回复于 2006-08-06 15:58:41 得分 0

调用约定啊  
   
  不写的话编译器缺省认为_cdeclTop

4 楼danvy_chan()回复于 2006-08-06 16:02:29 得分 0

是否可以理解为这并非完全遵照C的语法,而是MS自己添加的东西?  
   
  那么WINAPI与_cdecl有什么区别呢?Top

5 楼mscf(扎西特勒)回复于 2006-08-06 16:09:48 得分 0

Microsoft函数调用约定    
   
   
  对于所有调用共有的约定:ebx、ebp、esi、edi都是calle-save,即由被调用的函数负责它们的保存(如果被调用函数用到了这些寄存器的话)  
   
  先看函数调用发生了什么:(win32下)  
  1、所有参数提升到4bytes的倍数  
  2、执行call指令  
  3、将ebx、ebp、esi、edi保存在栈上,这一步称为function   prolog  
  4、将返回值放在eax中(返回int64放在edx:eax中,返回double放在浮点寄存器中。复杂的数据结构在caller的栈中分配空间,将首地址做为最后压栈的参数(我拿__cdecl试的),callee返回的时候将返回值放在这个指针指向的地址)  
  5、取出ebx、ebp、esi、edi,这一步称为function   epilog  
  6、清空栈,保持堆栈平衡,这一步称为stack   cleanup  
   
  具体的调用约定:  
  1、__cdecl  
  压栈顺序:从右至左  
  清栈:函数调用者负责清空,称为caller   cleanup  
  名字修饰(name   decoration):在函数名前加上下划线做前缀,比如_foo  
  注:c/c++函数的缺省调用约定  
   
  2、__stdcall  
  压栈顺序:从右至左  
  清栈:被调用函数负责清空,称为callee   cleanup  
  名字修饰:在函数名前加上下划线做前缀,名字后用@加上函数参数大小做后缀,如_foo@8  
  注:WINAPI就是__stdcall的#define  
   
  3、__fastcall  
  压栈顺序:第一个参数放在ecx,第二个参数放在edx,其余从右至左  
  清栈:callee   cleanup  
  名字修饰:在函数名前加上@做前缀,名字后用@加上函数参数大小做后缀,如@foo@8  
  注:名字叫fast实际就不一定了……  
   
  4、thiscall  
  压栈顺序:this指针(cpp非静态成员函数特有)放在ecx,其余从右至左  
  清栈:callee   cleanup  
  注:cpp非静态成员函数默认的调用约定  
   
  5、naked  
  压栈顺序:从右至左  
  清栈:caller   cleanup  
  注:VxDs用的调用约定,将__declspec(naked)写在函数定义处(注意,不是声明)  
   
  这篇文章把naked作为calling   convention:   http://www.cs.cornell.edu/courses/cs412/2001sp/resources/microsoft-calling-conventions.htm    
   
  但naked应该算不上调用约定了,只是单纯地将c/c++代码翻译成asm,连esp、ebp之间的保存、mov都没有就直接拿ebp来寻址了,函数结束后也不管ret,太naked了!  
   
  补充:c允许可变参数(例如printf),为了方便地使用这些函数,所以__cdecl要  
  1、从右至左压栈(这样才能知道第一个参数在堆栈中的地址)  
  2、caller   cleanup(因为只有caller才知道这次调用push了多少参数  
   
   
  函数调用约定的历史——16位的世界:  
   
  对所有的调用约定:  
  1、用dx:ax或ax保存返回值  
  2、由于cx不能寻址,所以还需要一个bx来scratch(就是不需要callee-save的寄存器)  
   
  具体的调用约定  
  1、__cdecl  
  名字修饰在函数前加下划线可能是为了区别函数名和汇编语言的关键字  
   
  2、__pascal  
  自左至右传参、callee   cleanup  
  比较有意思的是名字修饰把函数名转换为大写,嗯,pascal大小写无关……  
  几乎所有的win16函数都是用pascal调用约定,因为callee-clean的操作比caller-clean要节省3bytes的空间  
   
  3、__fortran  
  和pascal一样  
   
  4、__fastcall  
  和win32下一样,把ecx、edx换为cx、dx罢了  
  这个fast可是未必,如果函数中的计算要用到cx、dx就免不了把cx、dx压栈的操作了,所以这种调用约定仅仅可能对短小的leaf   function(就是不调用其他函数的函数)快一些,甚至对这类函数都快不了……Top

6 楼snowbirdfly(专心搞好嵌入式~~~)回复于 2006-08-06 16:23:45 得分 0

呵呵~  
  楼上说的很多阿~~  
  除了int   WINAPI   WinMain,向API里面有很多的回调~~  
  像LRESULT   CALLBACK   WndProc等~~~Top

7 楼danvy_chan()回复于 2006-08-06 16:25:45 得分 0

谢谢mscf!怎么结束讨论并给你分数啊,不会用...Top

8 楼believefym(feng)回复于 2006-08-06 16:26:37 得分 0

#define   WINAPI             __stdcallTop

相关问题

关键词

得分解答快速导航

  • 帖主:danvy_chan
  • mscf

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo