本文共 2084 字,大约阅读时间需要 6 分钟。
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利用这个机会在回调函数中处理消息或完成一定的操作。 回调函数还与Hook函数相类似,Hook函数只是回调函数的一个特例。习惯上把与SetWindowsHookEx函数一起使用的回调函数称为钩子函数。也有人把利用VirtualQueryEx安装的函数称为钩子函数,不过这种叫法不太流行。 下面是一个动态库与应用程序之间,实现回调函数的例子,重在说明回调函数的实现机制,至于内部代码,根据自己程序需要来更改. 步骤: 1、在动态库中: 1.1 声明应用程序中回调函数的原形,例子如下: typedef int (WINAPI *PFCALLBACK)(int Param1, int Param2); 2.2 定义回调函数类型: PFCALLBACK gCallBack = 0; 3.3 写被应用程序调用的接口函数: extern "C" void WINAPI TestCallBack(PFCALLBACK Func) { if(Func == NULL) return; gCallBack = Func; DWORD ThreadID = 0; HANDLE hThread = CreateThread(NULL, 0, Thread1, LPVOID(0), 0, &ThreadID); return; } 4.4 写Thread1这个过程: DWORD WINAPI Thread1( LPVOID lpParameter // thread data ) { TCHAR Buffer[256]; HDC hDC = GetDC(HWND_DESKTOP); int Step=1; MSG Msg; DWORD StartTick; //一个延时循环 for(;Step<200;Step++) { StartTick = GetTickCount(); /*这一段为线程交出部分运行时间以让系统处理其他事务*/ for(;GetTickCount()-StartTick<10;) { if(PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } } /*把运行情况打印到桌面,这是vcbear调试程序时最喜欢干的事情*/ sprintf(Buffer,"Running %04d",Step); if(hDC!=NULL) TextOut(hDC,30,50,Buffer,strlen(Buffer)); } /*延时一段时间后调用回调函数*/ (*gCallBack)(Step,1); /*结束*/ ::ReleaseDC(HWND_DESKTOP,hDC); return 0; } 2、在应用程序中: 2.1 在头文件中,声明回调函数原形,并定义应用程序实例句柄: typedef int (WINAPI *PFCALLBACK)(int Param1, int Param2); HINSTANCE m_handle; 2.2 在执行文件中加载动态库: m_handle = LoadLibrary("CallBack_Dll.dll"); 2.3 在一个按钮事件中,调用动态库接口函数: void CVC_CallBackDlg::OnCallBack() { // TODO: Add your control notification handler code here typedef void (WINAPI *PTestCallBack)(PFCALLBACK); PTestCallBack addFun; //函数指针 addFun = (PTestCallBack)GetProcAddress(m_handle, "TestCallBack"); addFun(CBFunc); } 2.4 写回调函数过程: int WINAPI CBFunc(int Param1, int Param2) { int res = Param1 + Param2; CHAR Buffer[256] = ""; sprintf(Buffer, "callback result = %d", res); ::MessageBox(NULL, Buffer, "Test", MB_OK); //演示回调函数被调用 return res; } 2.5 在窗口退出时,释放应用程序实例句柄: void CVC_CallBackDlg::OnCancel() { // TODO: Add extra cleanup here FreeLibrary(m_handle); CDialog::OnCancel(); } 转载地址:http://dxtgi.baihongyu.com/