以下为DLL文件
#include "stdafx.h"
#include "iostream"
//-----------------------------------------------------------------------------------
HWND windowsJB=NULL; // 窗口句柄
HHOOK mouseHookJB=NULL; // 鼠标钩子句柄
HWND TargetWindowsJB;//鼠标所指向的窗口的句柄
HWND FuWindowsJB;//鼠标所指向的窗口的父窗口的句柄
HINSTANCE dllInstanceJB=NULL; // DLL实例句柄
//-----------------------------------------------------------------------------------
void StartHook(HWND,bool);
LRESULT WINAPI MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
//void StopHook();
//-------------------------------------------------------------------------------------
BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}
//--------------------------------------------------------------------------------------
void StartHook(HWND TargetWindowsJB,bool nCode)
{
    if(nCode)
{
    FuWindowsJB=TargetWindowsJB;
    mouseHookJB=SetWindowsHookEx(WH_MOUSE,MouseProc,dllInstanceJB,0);
}
else
    UnhookWindowsHookEx(mouseHookJB);} 
//--------------------------------------------------------------------------------------
LRESULT WINAPI MouseProc(int nCode,WPARAM wParam,LPARAM lParam)//鼠标钩子的处理函数
{
   MOUSEHOOKSTRUCT * pMouseHook; 
   pMouseHook=(MOUSEHOOKSTRUCT *) lParam;
    if(nCode>=0)
      {
TargetWindowsJB=pMouseHook->hwnd;          
         FuWindowsJB=TargetWindowsJB; //用当前获得的窗口句柄填充到父窗口句柄变量里
      while(FuWindowsJB !=NULL)
         {
           TargetWindowsJB=FuWindowsJB; 
           FuWindowsJB=GetParent(TargetWindowsJB); //取应用程序主窗口句柄
         } 
      if(TargetWindowsJB != windowsJB) 
         { 
          
  char szCaption[100]; //存储窗体标题的变量
           GetWindowText(TargetWindowsJB,szCaption,100); //取目标窗口标题
           std::cout<<"DLL is ok"<<std::endl;
           Sleep(20000); 
          } 
      }
    return CallNextHookEx((HHOOK) mouseHookJB,nCode,wParam,lParam); //继续传递消息 

//---------------------------------------------------------------------------------------
以下是调用该DLL的代码
#include "stdafx.h"
#include "windows.h"
typedef VOID (* MYPROC)(int,HINSTANCE);
HINSTANCE hinstLib;//DLL文件句柄
MYPROC ProcAdd; 
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
int _tmain(int argc, _TCHAR* argv[])
{
    hinstLib = LoadLibraryEx("test.dll",NULL,DONT_RESOLVE_DLL_REFERENCES);
    if (hinstLib != NULL) 
     { 
        ProcAdd = (MYPROC) GetProcAddress( hinstLib,"StartHook");         
        if (ProcAdd==NULL) 
          {
            fRunTimeLinkSuccess = TRUE;
   std::cout<<"函数没有载入"<<std::endl;
   Sleep(20000);
           }
        fFreeResult = FreeLibrary(hinstLib); 
    }  
    if (! fRunTimeLinkSuccess) 
        printf("Message via alternative method\n");
    Sleep(20000);
}
//-----------------------------------------------------------------
现在的问题是能载入DLL但不能调用DLL中的函数,请大家帮我看看原因。我是个新手,一下子在学DLL编写和HOOK的编写实在有点吃力。先给20分,分不够可以再加。

解决方案 »

  1.   

    你在调用的时候 StartHook 函数参数定义错了
    应该是:
    typedef VOID (* MYPROC)(HWND,bool);
      

  2.   

    楼上的朋友说的对。但你指出的只是一个问题,我修改后还是不能调用。后来我又在DLL源文件中的
    void StartHook(HWND,bool)前加上了“extern "C" _declspec(dllexport)”,这下就行了。可是问题是我编写的是非MFC的DLL,难道也需要“extern "C" _declspec(dllexport)”这些语句吗?
      

  3.   


    或者使用DEF文件指定导出函数也可以
      

  4.   

    加extern "C"或者不加,在生成的引出函数名上有区别,这点区别就能导致你根本没有办法用期望的函数名去调用函数。
      

  5.   

    现将程序做了如下改动:
    DLL部分
    #include "stdafx.h"
    #include "stdio.h"
    #include "iostream"
    //---------------------------------------------------------------
    HWND windowsJB=NULL; // 窗口句柄
    HHOOK mouseHookJB=NULL; // 鼠标钩子句柄
    HWND TargetWindowsJB;//鼠标所指向的窗口的句柄
    HWND FuWindowsJB;//鼠标所指向的窗口的父窗口的句柄
    HINSTANCE dllInstanceJB=NULL; // DLL实例句柄
    FILE *fp;
    //--------------------------------------------------------------
    extern "C" __declspec(dllexport) void StartHook(HWND,bool);
    LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
    void StopHook();
    //--------------------------------------------------------------------
    BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
        return TRUE;
    }
    //--------------------------------------------------------------
    void StartHook(HWND TargetWindowsJB,bool nCode)
    {
    std::cout<<"StartHook"<<std::endl;
    Sleep(5000);
    mouseHookJB=SetWindowsHookEx(WH_MOUSE,MouseProc,dllInstanceJB,0);

    //-------------------------------------------------------------------
    LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
       if (nCode<0) return CallNextHookEx (mouseHookJB,nCode,wParam,lParam); 
       MOUSEHOOKSTRUCT * pMouseHook; 
       pMouseHook=(MOUSEHOOKSTRUCT *) lParam;
       if (nCode==HC_ACTION) 
       {
     
           TargetWindowsJB=pMouseHook->hwnd; 
           FuWindowsJB=TargetWindowsJB; 
           while(FuWindowsJB !=NULL)
             {
               TargetWindowsJB=FuWindowsJB; 
               FuWindowsJB=GetParent(TargetWindowsJB); 
               char szCaption[100]; //存储窗体标题的变量
               GetWindowText(TargetWindowsJB,szCaption,100); //取目标窗口标题
               fp=fopen("c:\a.txt","w+");
               fputs(szCaption,fp);
      fclose(fp);

          }
        return CallNextHookEx( mouseHookJB,nCode,wParam,lParam); 

    //-----------------------------------------------------------------
    /*最后,调用UnhookWindowsHookEx()函数完成对钩子的卸载*/
    void StopHook()
    {
      UnhookWindowsHookEx(mouseHookJB);

    //---------------------------------------------------
    调用部分
    #include "stdafx.h"
    #include "windows.h"
    typedef char (* MYPROC)(HWND,bool);
    HINSTANCE hinstLib;//DLL文件句柄
    MYPROC ProcAdd; 
    int _tmain(int argc, _TCHAR* argv[])
    {
        hinstLib = LoadLibrary("test.dll");
        if (hinstLib != NULL) 
        { 
            ProcAdd = (MYPROC) GetProcAddress( hinstLib,"StartHook");         
            if (ProcAdd==NULL) 
            {
     std::cout<<"函数没有载入"<<std::endl;
    Sleep(5000);
            }
            FreeLibrary(hinstLib); 
         }
    }
    请问用控制台可以调用带DLL的钩子吗?在控制台下应该如何调试这个鼠标钩子呢?
    现在的代码能找到DLL文件,也能找到StartHook函数,可似乎没起任何作用,连在C盘上创建文件都不行。望大家指教,分不够可以再加。
      

  6.   

    现在还有个问题。就是在调用该DLL的代码中为什么非要加入“ProcAdd(1,hinstLib);”这句语句才会去调用DLL中的"StartHook”函数?源代码如下:
    hinstLib = LoadLibrary((LPCTSTR)"test.dll");
        if (hinstLib != NULL) 
        { 
           ProcAdd = (MYPROC) GetProcAddress( hinstLib,"StartHook");
           if (ProcAdd)
            {
                handletype=1;
       ProcAdd(1,hinstLib);
             }        
           FreeLibrary(hinstLib); 
        }
    难到单是ProcAdd = (MYPROC) GetProcAddress( hinstLib,"StartHook");语句不行吗?MSDN 好像也没有说过啊。
      

  7.   

    要用#pragma data_seg("名字")声明一个段,并且加上#pragma comment(linker,"/SECTION:名字,rws")声明这个段共享.
      

  8.   

    你首先要保证DLL中的函数压栈方式要和APP中一样。
    你在DLL中定义的CALLBACK (就是__stdcall) VC 默认的是__cdecl,
    所以你在APP中也应该这样声明:
    typedef char (*CALLBACK MYPROC)(HWND,bool);ProcAdd(1,hinstLib)相当于一个函数调用。如果你的DLL要注入到其他进程,那么你全局变量是会有用的,因为
    两个进程的地址空间不一样。你应该声明一个共享段
    #pragma data_seg("ShareData"
    HWND hwnd2Rec = NULL;
    #pragma data_seg()
    #pragma comment(linker, "/SECTION:ShareData,RWS") //中间没有空格。