我正在查看SDL库中的一些代码,并遇到了一个声明如下的函数:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
现在,我是德尔福编码器。没有hablo C muy bien,先生。但是我记得我的大学课程中有足够的语法来读它:
函数名称是WndProc。参数列表非常明显。函数返回类型是LRESULT。但是世界上那个“CALLBACK”在那里做什么呢?在Delphi中,任何函数都可以用作回调函数;你只需要传递正确类型的函数指针。有什么特别的原因导致C不能这样工作吗?或者它意味着什么不同?
答案 0 :(得分:14)
“CALLBACK”是一种调用约定。还有其他类型的调用约定。 CALLBACK与__stdcall相同。
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557
Raymond Chen博客上的更多信息:
http://blogs.msdn.com/oldnewthing/archive/2004/01/08/48616.aspx
答案 1 :(得分:4)
Raymond Chen的博客简短摘要:
关于打电话的好处 x86平台上的约定是 有很多可供选择!
C调用约定(__cdecl)
C调用约定受到约束,因为它允许使用具有可变数量参数的函数。它几乎要求堆栈被调用者清理并且参数被从右向左推,因此第一个参数位于相对于堆栈顶部的固定位置。总结:调用者清理堆栈,参数从右向左推。
Pascal调用约定(__pascal )
Pascal不支持具有可变数量参数的函数,因此它可以使用callee-clean约定。参数从左向右推。几乎所有的Win16函数都被导出为Pascal调用约定。 callee-clean约定在每个调用点保存三个字节,每个函数有两个字节的固定开销。它也快一点。在Win16上,节省几百个字节和几个周期是一个大问题。注意:Fortran调用约定(__fortran)与Pascal调用约定
相同答案 2 :(得分:2)
这是召唤大会。将指向此函数的指针传递给后来调用该函数的Windows API时,需要它。 Windows调用约定与C调用约定不同,因此您需要向编译器指定WndProc()是特殊的,并且它需要不同的启动和清理代码。
答案 3 :(得分:0)
这是一个调用约定,Delphi也有它们。尝试在Delphi帮助中查找'cdecl'。在Delphi(或者像我们老兄喜欢调用它的Object Pascal)中,调用约定出现在函数声明之后,就像这样;
function MyFunction(X, Y: Real): Real; cdecl;