我正在查看SDL库中的一些代码,发现了一个如下所示的函数:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
现在,我是一个Delphi编码器。 没有哈布罗·C·穆迪·比,传感器。 但是我记得我的大学课程有足够的语法来读取它:
函数名是WndProc。 参数列表是相当不言自明的。 函数返回types是LRESULT。 但是在这个世界上呢,在那里做“CALLBACK”呢? 在Delphi中,任何函数都可以用作callback; 你只需要传递正确types的函数指针。 为什么C不这样工作有什么特别的原因? 或者这意味着什么不同?
“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
来自Raymond Chen博客的简短综述:
在x86平台上调用约定的好处是有太多的选择!
C调用约定(__cdecl)
C调用约定是受约束的,因为它允许使用具有可变数目参数的函数。 它几乎要求堆栈被调用清理,并且参数被从右向左推,以便第一个参数相对于堆栈的顶部是固定的位置。 总之:调用者清除堆栈,参数从右向左推。
帕斯卡调用约定(__帕斯卡 )
Pascal不支持具有可变数量参数的函数,因此可以使用被调用者清除约定。 参数从左向右推。 几乎所有的Win16函数都作为Pascal调用约定输出。 被调用者清除约定在每个调用点保存三个字节,每个函数有两个字节的固定开销。 它也快一点。 在Win16上,节省几百个字节和几个周期是一件大事。 注意:Fortran调用约定(__fortran)与Pascal调用约定相同
这是调用惯例。 将指向此函数的指针传递给稍后调用该函数的Windows API时,这是必需的。 Windows调用约定与C调用约定不同,因此您需要向编译器指定WndProc()是特殊的,并且需要不同的启动和清理代码。
这是一个调用约定,德尔福也有它们。 尝试在Delphi帮助中查找“cdecl”。 在Delphi(或者像我们老调的那样称为Object Pascal)中,调用约定是在函数声明之后出现的,就像这样;
function MyFunction(X, Y: Real): Real; cdecl;