的所以产生使用回调这个想法是现在使用VC和Delphi混合编程用VC写个DLL进行些时间比较长异步工作工作完成的后需要通知使用DLL应用:某些事件已经完成,请处理事件后续部分开始想过使用同步对象文件影射消息等实现DLL到应用通知后来突然想到可不可以在应用端先写个等需要处理后续事宜时候在DLL里直接这个即可
于是就动手写了个回调原形在VC和 Delphi里都进行了测试
:声明回调类型
vc版
typedef (WINAPI *PFCALLBACK)( Param1, Param2) ;
Delph版
PFCALLBACK = function(Param1:eger;Param2:eger):eger;stdcall;
实际上是声明了个返回值为,传入参数为两个指向指针
由于C和PASCAL编译器对参数入栈和返回处理有可能不致把类型用WINAPI(WINAPI宏展开就是__stdcall)或stdcall统修饰
2:声明回调原形
声明原形
vc版
WINAPI CBFunc( Param1, Param2);
Delphi版
function CBFunc(Param1,Param2:eger):eger;stdcall;
以上为全局如果要使用个类里作为回调原形把该类声明为静态即可
3: 回调者
回调我把它放到了DLL里这是个很简单VC生成WIN32 DLL.并使用DEF文件输出其名 TestCallBack实现如下:
PFCALLBACK gCallBack=0;
void WINAPI TestCallBack(PFCALLBACK Func)
{
(FuncNULL);
gCallBack=Func;
DWORD ThreadID=0;
HANDLE hThread = CreateThread(
NULL,
NULL,
Thread1,
LPVOID(0),
&ThreadID
);
;
}
此工作把传入 PFCALLBACK Func参数保存起来等待使用并且启动个线程声明了个指针PFCALLBACK gCallBack保存传入地址
4: 回调如何被使用:
TestCallBack被后启动了个线程作为演示线程人为进行了延时处理并且把线程运行过程打印在屏幕上.
本段线程代码也在DLL工程里实现
ULONG WINAPI Thread1(LPVOID Param)
{
TCHAR Buffer[256];
HDC hDC = GetDC(HWND_DESKTOP);
Step=1;
MSG Msg;
DWORD StartTick;
//个延时循环
for(;Step<200;Step)
{
StartTick = GetTickCount;
/*这段为线程交出部分运行时间以让系统处理其他事务*/
for(;GetTickCount-StartTick<10;)
{
(PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
/*把运行情况打印到桌面这是vcbear调试时最喜欢干事情*/
sprf(Buffer,"Running %04d",Step);
(hDC!=NULL)
TextOut(hDC,30,50,Buffer,strlen(Buffer));
}
/*延时段时间后回调*/
(*gCallback)(Step,1);
/*结束*/
::ReleaseDC (HWND_DESKTOP,hDC);
0;
}
5:万事具备
使用vc和Delphi各建立了个工程编写回调实现部分
VC版
WINAPI CBFunc( Param1, Param2)
{
res= Param1+Param2;
TCHAR Buffer[256]="";
sprf(Buffer,"callback result = %d",res);
MessageBox(NULL,Buffer,"Testing",MB_OK); //演示回调被
res;
}
Delphi版
function CBFunc(Param1,Param2:eger):eger;
begin
result:= Param1+Param2;
TForm1.Edit1.Text:=tostr(result); / /演示回调被
end;
使用静态连接思路方法连接DLL里出口 TestCallBack,在工程里添加 Button( 对于Delphi工程还需要在Form1上放个EditControl控件默认名为Edit1)
响应ButtonClick事件 TestCallBack
TestCallBack(CBFunc) //参数CBFunc为回调地址
创建线程后立刻返回应用可以同时干别事情去了现在可以看到屏幕上不停显示串表示dll里创建线程运行正常会的后线程延时部分结束结束vc应用弹出MessageBox,表示回调被并显示根据Param1Param2运算结果DelphieditControl控件里文本则被改写成Param1Param2 运算结果
可见使用回调编程模式可以根据区别需求传递区别回调地址或者定义各种回调原形(同时也需要改变使用回调参数和返回值约定)实现多种回调事件处理可以使控制灵活多变也是种高效率清晰模块的间耦合方式在些异步或复杂系统里尤其有用 -- 你可以在个模块(如DLL)里专心实现模块核心业务流程和技术功能外围扩展功能只给出个回调接口通过其他模块传递过来回调地址方式将后续处理无缝地交给另个模块随它按自定义方式处理
本文例子使用了在DLL里多线程延时后回调方式只是为了突出下回调效果其实只要是在本进程的内都可以随你高兴可以把地址传递来传递去当成回调使用
这样编程模式原理非常简单单:就是把也看成个指针个地址来没有什么别复杂东西仅仅是编程里个小窍门技巧至于回调模式究竟能为你带来多少好处就看你是否使用如何使用这种编程模式了
最新评论