指向DLL中的回调的指针

时间:2010-12-04 07:14:59

标签: c++ c winapi visual-c++

我正在调用一个Dialog,它在DLL中有资源和dlg-procedure。 我没有使用DEF文件或LIB文件。函数名称是已知的,函数args是已知的,我使用GetProcAddress来获取指向我感兴趣的函数的指针。

'为什么'我这样做是没有意义的,这是'学习'的实验。

这适用于_ CDECL功能,但回调(的_stdcall),我不能让一个指针到实际的对话程序(它返回0)。

以下是我的指示:

//////////////////// DLL TEST STUFF ////////////////////////////

#define   DLLPATH "../../testdll/release/testdll.dll"

//typedef some function pointers
typedef HINSTANCE        (__cdecl *INSTPROC )(void); 
typedef int              (__cdecl *VOIDPROC )(void); 
typedef LRESULT          (__stdcall *DLGROC )(HWND, UINT, WPARAM, LPARAM );

///////////////////////////////////////////////////////////////

正如我所说的,任何不是回调的函数都会返回一个有效的结果,另外,对话框会按预期弹出,DLL的HINSTANCE没有问题。

但如果没有指向dlgproc的指针,那么任何按钮消息都无处可去。

以下是一些测试代码:

 //use DLL funcs without lib or def files

                              //this works
  GetInst = (INSTPROC)GetProcAddress(Loadme,"getinst");
                              //this works
  GetID   = (VOIDPROC)GetProcAddress(Loadme,"getid");
                              //this doesn't work, rets 0
  DlgProc = (DLGPROC) GetProcAddress(Loadme,"dllProc");

  //test for result
  dllid  =(GetID)();
  dllinst=(GetInst)();

  //compare hinst            OK
  wsprintf(buf,"dllinst=%x  Loadme=%x",dllinst, Loadme);
  MessageBox(hwnd,buf,"",MB_OK);

  //check resOurce ID        OK
  wsprintf(buf,"GetID returned: %d",dllid);
  MessageBox(hwnd,buf,"",MB_OK);

  //check dllProc addr       NOGO, ret=0
  wsprintf(buf,"dllProc=%x",DlgProc);
  MessageBox(hwnd,buf,"",MB_OK);

        //    DLL instance,        resource ID,     parent,  dlgproc    
        DialogBox(Loadme  ,  MAKEINTRESOURCE(dllid),  hwnd,  DlgProc);

  //dialog loads and shows, can't get dlgproc addr 

        FreeLibrary(Loadme);
        ///////////////// END DLL TEST STUFF ///////////////

在DLL方面,它看起来像这样:

__declspec(dllexport) LRESULT CALLBACK dllProc(
                                            HWND hwnd, 
              UINT Message, 
              WPARAM wParam, 
              LPARAM lParam
              )
{

hpwnd=hwnd;

 switch (Message){

  case WM_INITDIALOG:
   MessageBox(hwnd,"At DlgProc...","",MB_OK);
  return TRUE;

  case WM_COMMAND:
   switch(LOWORD(wParam)){
       case IDEND:
    case IDCANEND:
      EndDialog(hwnd,0);
   return TRUE;
    }
 return TRUE;
 }
return FALSE;
}

此时此刻无关紧要,因为我无法在第一时间获得指向回调的指针。

如果有人碰巧知道获取指向回调的指针的修复程序,我将非常感谢您的输入。

感谢您的耐心等待。

1 个答案:

答案 0 :(得分:2)

你需要在extern "C"块中声明你的dllProc,以防止在导出时对其名称进行修饰,这样当你要求一个名为“dllProc”的函数时,会找到这样一个函数(而不是“dllProc @ blahmoocow”) “或者C ++装饰产生的任何疯狂。: - ))。

将此声明放在dllProc定义之前:

extern "C"
{
    __declspec(dllexport) LRESULT CALLBACK dllProc(
           HWND hwnd, UINT Message, WPARAM wParam, PARAM lParam);
}

您也可以从dllProc定义中删除__declspec(dllexport)