回调函数与Delphi的事件模型
回调函数:
回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象、全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的函数地址传递给该对象。这个函数就是调用者和被调用者之间的一种通知约定,当约定的事件发生时,被调用者(一般会包含一个工作线程)就会按照回调函数地址调用该函数。
这种方式,调用者在一个线程,被调用者在另一个线程。
在Windows API中有一些函数使用回调函数,例如CreateThread、SetWindowLong等。对应的回调函数定义为如下形式:
function CallBackFunc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint;stdcall;
procedure ThreadFunction(Ptr: Pointer);stdcall;
消息:
消息也可以看作是某种形式的回调,因为消息也是在初始化时由调用者向被调用者传递一个句柄和一个消息编号,在约定的事件发生时被调用者向调用者发送消息。
这种方式,调用者在主线程中,被调用者在主线程或者工作线程中。
Delphi事件模型:
在Delphi的VCL中有很多可视化组件都是使用事件模型,例如TForm的OnCreate事件,其原理是:在设计时指定事件函数,在运行时事件触发,则会调用在设计时指定的事件函数。
在机制上,Delphi事件模型与回调是一样的。但具体形式有些区别,纯的回调函数是全局函数的形式,而Delphi事件是对象方法的形式,即可以定义如下回调函数类型
type
TCallBackFunc = procedure (pData: Pointer) of object;
这就使得Delphi事件只能在Delphi内部使用,而回调函数是可以跨语言的。
另外还要注意,回调函数一般(在Delphi的组件是在主线程中)是在回调体中创建的线程,因此要有临界区保护。