代码如下:typedef void (CALLBACK *MYPROC)( BOOL bAdd );// dll 的导出函数
BOOL DLLAPI Init( MYPROC proc )
{
if( NULL == proc || NULL != g_hHook )
return FALSE; g_Proc = proc; g_hHook = SetWindowsHookEx( WH_CALLWNDPROC, (HOOKPROC)hook_proc, g_hInstance, 0 );
return (NULL != g_hHook);
}// 钩子函数
LRESULT CALLBACK hook_proc( UINT nCode, WPARAM wParam, LPARAM lParam )
{
CWPSTRUCT *pMsg = (CWPSTRUCT*)lParam; if( HC_ACTION == nCode ) {
if( g_hWnd == pMsg->hwnd ) {
switch( pMsg->message ) {
case TB_INSERTBUTTON:
OnInsertButton();
break;
case TB_DELETEBUTTON:
OnDeleteButton();
break;
default:
break;
}
CallNextHookEx( g_hHook, nCode, wParam, lParam );
return 0;
}
} return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}void OnInsertButton()
{
if( NULL == g_Proc )
MessageBox( NULL, _T("g_Proc is null !"), _T("InsertButton"), MB_OK );
else
g_Proc( TRUE );
}void OnDeleteButton()
{
if( NULL == g_Proc )
MessageBox( NULL, _T("g_Proc is null !"), _T("DeleteButton"), MB_OK );
else
g_Proc( FALSE );
}// 测试程序提供的回调函数
void CALLBACK MyProc( BOOL bAdd )
{
if( bAdd )
MessageBox( NULL, _T("MyProc ADD"), _T("Msg"), MB_OK );
else
MessageBox( NULL, _T("MyProc DEL"), _T("Msg"), MB_OK );
}
测试结果:
如果我把 g_Proc 放到共享数据段#pragma data_seg( "MyHook" )
TRAYPROC    g_Proc   = NULL;
#pragma data_seg()#pragma comment( linker, "/section:MyHook,RWS" )则测试程序调用函数 g_Proc 的时候会导致 explore.exe 崩溃。如果我不把 g_Proc 放到共享数据段,则测试程序会弹出对话框说 g_Proc is null !请问如何才能让 g_Proc 正确运行 ...... ?

解决方案 »

  1.   

    SetWindowsHookEx最后一个参数,指定为0的话会勾系统中所有线程和进程。你Init时传入的函数指针是某个进程内的,其他进程的这个地址可能未分配,也可能是其他数据,一调用当然要挂了。共享数据段的数据是在页面文件中的,所有进程看到的都是一样的。
      

  2.   

    ::ExitInstance() 函数有问题,肯定挂了!
      

  3.   

    exe中实现,dll通过进程间通信叫exe执行这个函数
      

  4.   


    我提供的 dll 外部实现,也就是他的 exe 中实现
      

  5.   

    是的,因为 dll 中安装了一个全局钩子
      

  6.   


    你不把函数放在DLL中让其他进程加载,其他进程是不可能调用得到的,没有其他方法。
      

  7.   

    如果exe是调用dll中的一个导出函数来安装钩子,你可以在dll中增加一段程序,这段程序由安装钩子的进程调用,它创建一个线程,这个线程专门等待一个自定义消息,等到了消息后就通过消息的参数调用exe中提供的回调函数,其它加载这个dll的进程就通过dll中的另一段程序向这个线程发送消息使其执行回调函数