hook的回调函数必须写在dll中么
1个回答
展开全部
使用回调函数实际上就是在调用某个函数(通常是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();
}
至此,动态库与应用程序的整个回调函数实现过程,就实现了。
回调函数还与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();
}
至此,动态库与应用程序的整个回调函数实现过程,就实现了。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询