查看文章
 
动态库与应用程序的回调函数
2007-09-14 14:52

     在很多编程过程中,我们遇到回调函数的情况很多,无论是一个应用程序内部,还是应用程序与动态库之间,都会经常涉及到回调函数的编程.那么什么是回调函数呢,它的实现机制是什么呢?下面我就简单在这里介绍一下:

     使用回调函数实际上就是在调用某个函数(通常是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();
}

     至此,动态库与应用程序的整个回调函数实现过程,就实现了。

     如果还有不明白的,与我联系,QQ : 14369700


类别:编程||添加到搜藏 |分享到i贴吧|浏览(929)|评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu