Указатель на обратный вызов в DLL - PullRequest
3 голосов
/ 04 декабря 2010

Я вызываю диалог, в котором есть ресурсы и процедура dlg в DLL.Я не использую файл DEF или файл LIB.Имена функций известны, аргументы функций известны, я использую GetProcAddress, чтобы получить указатель на интересующие меня функции.

«Почему» Я делаю это таким образом, не имеет значения, это эксперимент по «обучению».

Это работает на _ функциях cdecl, но на CALLBACK ( _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 Ответ

2 голосов
/ 04 декабря 2010

Вам нужно объявить ваш dllProc внутри блока extern "C", чтобы предотвратить его оформление при экспорте, чтобы при поиске функции с именем "dllProc" была найдена такая функция (вместо "dllProc @ blahmoocow" или все безумие, которое производит C ++ украшение.: -)).

Поместите это объявление перед определением dllProc:

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

Вы также можете удалить __declspec(dllexport) из определения dllProc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...