hook的回调函数必须写在dll中么

 我来答
福喜900
2015-02-09 · TA获得超过6.1万个赞
知道大有可为答主
回答量:1.1万
采纳率:0%
帮助的人: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();
}

至此,动态库与应用程序的整个回调函数实现过程,就实现了。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式