11

我正在查看SDL库中的一些代码,并遇到了一个声明如下的函数:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

现在,我是一名 Delphi 编码员。没有 hablo C muy bien,先生。但我记得我大学课程的语法足够多,可以这样阅读:

函数名称是 WndProc。参数列表是不言自明的。函数返回类型是 LRESULT。但是那个“CALLBACK”到底在做什么呢?在 Delphi 中,任何函数都可以用作回调;您只需要传递正确类型的函数指针。有什么特别的原因导致 C 不能这样工作吗?或者它是否意味着不同的东西?

4

4 回答 4

15

“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

于 2009-02-09T23:18:20.913 回答
4

Raymond Chen 博客的简短综述:

在 x86 平台上调用约定的好处是有很多可供选择!

C 调用约定 (__cdecl)

C 调用约定受到限制,因为它允许使用具有可变数量参数的函数。它几乎需要调用者清理堆栈并将参数从右向左推送,以便第一个参数相对于堆栈顶部位于固定位置。总结:调用者清理堆栈,参数从右向左推送。

Pascal 调用约定 (__pascal )

Pascal 不支持具有可变数量参数的函数,因此它可以使用 callee-clean 约定。参数从左到右推送。几乎所有 Win16 函数都导出为 Pascal 调用约定。callee-clean 约定在每个调用点保存三个字节,每个函数有两个字节的固定开销。它也快了一点。在 Win16 上,节省几百字节和几个周期是一件大事。注意:Fortran 调用约定 (__fortran) 与 Pascal 调用约定相同

于 2009-02-09T23:34:43.683 回答
2

这是调用约定。当您将此函数的指针传递给稍后调用该函数的 Windows API 时,它是必需的。Windows 调用约定与 C 调用约定不同,因此您需要向编译器指定 WndProc() 是特殊的,并且它需要不同的启动和清理代码。

于 2009-02-09T23:23:05.723 回答
0

这是一个调用约定,Delphi 也有。尝试在 Delphi 帮助中查找“cdecl”。在 Delphi(或者我们老喜欢称之为 Object Pascal)中,调用约定出现在函数声明之后,如下所示;

function MyFunction(X, Y: Real): Real; cdecl;
于 2009-02-09T23:23:18.657 回答