我在浏览SDL库中的一些代码时,遇到了一个声明如下的函数:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
现在,我是一个 Delphi 程序员。不会C muy bien,先生。但我记得足够的语法从我的大学课程读它像这样:
函数名是WndProc。参数列表是非常不言自明的。函数返回类型是LRESULT。但是“CALLBACK”到底在那里做什么呢?在 Delphi 中,任何函数都可以用作回调函数;你只需要传递正确类型的函数指针。有什么特殊的原因为什么C不能那样工作?或者它有什么不同的含义吗?
4条答案
按热度按时间busg9geu1#
“CALLBACK”是一种调用约定。还有其他类型的调用约定。CALLBACK与__stdcall相同。
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557
更多信息请访问Raymond Chen的博客:
https://devblogs.microsoft.com/oldnewthing/20040108-00/?p=41163
wa7juj8i2#
来自Raymond Chen博客的简短综述:
在x86平台上调用约定的伟大之处在于有这么多可供选择!
C调用约定(__cdecl)
C调用约定是受约束的,因为它允许使用带有可变数量参数的函数。它几乎要求调用者清理堆栈,并将参数从右向左推送,以便第一个参数位于相对于堆栈顶部的固定位置。总结如下:调用方清除堆栈,参数从右向左推送。
Pascal调用约定(__pascal)
Pascal不支持参数数目可变的函数,因此它可以使用被调用方清除约定。参数从左向右推送。几乎所有Win 16函数都导出为Pascal调用约定。被调用方清除约定在每个调用点节省三个字节,每个函数的固定开销为两个字节。它也稍微快一些。在Win 16上,节省几百个字节和几个周期是一件大事。注意:Fortran调用约定(__fortran)与Pascal调用约定相同
t30tvxxf3#
这是一个调用约定。当你把一个指向这个函数的指针传递给一个Windows API时,它是必需的。Windows调用约定不同于C调用约定,因此你需要向编译器指定WndProc()是特殊的,它需要不同的启动和清理代码。
bkhjykvo4#
这是一个调用约定, Delphi 也有。试着在Delphi帮助中查找“cdecl”。在Delphi(或者我们老一代喜欢叫它Object Pascal)中,调用约定在函数声明之后,如下所示;