关于函数调用方式的问题

zhenyu362 2003-11-12 12:24:14
void WINAPI MyFunc( char c, short s, int i, double f );
WINAPI是什么调用方式??
几种常用调用方式不是 __cdecl __fastcall __stdcall 和 thiscall么??
而 __pascall __fortran __syscall是被淘汰的calling conventions,
我想问的是经常在函数前面见到 WINAPI CALLBACK 和 LRESULT 等几种修饰符,哪位大哥能帮我详细讲解一下么??

如果想回答“去找xxx书看看就知道了”之类的话那就省了吧!!
...全文
34 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lewolf 2003-11-12
  • 打赏
  • 举报
回复
既然都说:如果想回答“去找xxx书看看就知道了”之类的话那就省了吧!!
那还问什么?这些关键字和修饰符不是一句话能说清楚的,不看书,但凭帖子好像有些难度。
yjy1001 2003-11-12
  • 打赏
  • 举报
回复
都说了 —— 偶还能说什么
wind_flaw 2003-11-12
  • 打赏
  • 举报
回复
WINAPI就是__stdcall
#define WINAPI __stdcall
sfemil 2003-11-12
  • 打赏
  • 举报
回复
CALLBACK 也是 __stdcall
sfemil 2003-11-12
  • 打赏
  • 举报
回复
WINAPI 就是__stdcall
fatwave 2003-11-12
  • 打赏
  • 举报
回复
__fastcall和_fastcall是BCB是特有的关键字,只能用于修饰函数,其作用是指定函数使用“寄存器”调用规则,使用语法如下:
return_type __fastcall functionname(parmlist);
在BCB中,所有属于VCL的成员函数,必须是__fastcall 类型,编译器将“寄存器”调用规则和C调用规则、PASCAL及WIN32调用规则是同等对待的。
__finally保证块内代码的执行,
即使是出现了异常也是如此,所以在__finally中释放资源很合适

对于各种的call,看看汇编的结果很清楚,
例如对于函数:
void func(int a, int b, int c, int d) { }
使用函数如下
int main()
{
func(1, 2, 3, 4);
}

1.如果函数func是__cdecl(默认调用方式),调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
add esp 0x10 //调用者恢复堆栈指针esp,4个参数的大小是0x10(4x4)
}

2.如果函数func是__stdcall,调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__pascal,调用情况如下
int main()
{
//参数从左到右压栈
push 1
push 2
push 3
push 4
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__fastcall,调用情况如下
int main()
{
//参数先用ecx, edx, eax传递,然后再压栈
//不进栈
//(不知为什么,帮助中写的是从左到右传递的,
//是不是错了,还是BCB6和BCB5的不一样)
push 4
mov ecx 3
mov edx 2
mov eax 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x04",
//因为只进栈一个参数,其余用寄存器传递,所以用ret 0x04恢复
}

15. [C++ Warning] Dialogs.hpp(437): W8058 Cannot create pre-compiled header: initialized data in header
就是这个437号警告, 经常出现, 而且出错的地方又常常不在我的代码位置. 我不知道该如何修改我的代码来去除这个警告.
教你一绝招,c++Builder菜单Project/Options/Compiler/warnings中找到去掉W8058,然后去掉该项前的对号就可以了,其他的警告也是这样。

16. 我把数组定义为:int counter[1000][49]
但能存取到2500行的内容,即counter[2500][x],而且没有错误。这是为何?请各位指点。谢谢。
固定数组在内存中占用一块连续的空间,数组元素a[x][y],在访问内存时根据,x,y,的值来合成内存地址,以上面为例,连续的内存空间为1000*49*4字节,如果2500*x < 1000*49*4,可能不会出错,但是这已经出错了,偏离了程序的本意,建议使用动态数组,这样对上下标检查严格一点

定义一个数组,会采用栈内存.一般情况下,系统默认的栈内存不会超过2M左右,否则就会栈溢出.由于栈内存采用连续控件,所以你那种方式可以访问到,不过不会是你要的答案而已.如果是用堆内存就不行了,因为是动态分配的,不是连续的,所以就会出错.
zhenyu362 2003-11-12
  • 打赏
  • 举报
回复
哎,既然有了__stdcall 又还要搞一个WINAPI出来,这不是折磨人吗?
再跟我讲一下window procedure 和 callback function.
不是很理解,
对了,这里的大哥大姐都好热心哦,谢谢啦

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧