一個比較大點的程序。我想將其的中幾個模塊做成DLL.在主程序中顯示DLL中的對話框。
我做了個簡單的測試,如下:
//TestDll中:
void  _stdcall   ShowMain()
{
CMainDialog dlg;
dlg.DoModal();
}
//testDll.Def:
LIBRARY TestDll
EXPORTS 
     ShowMain @1
//測試程序中: 已設定testDll.lib
extern "C" void __stdcall ShowMain();
void CMainFrame::OnDllexport() 
{
ShowMain();
}
//程序運行時,在WinCore.cpp if (!AfxGetThread()->PumpMessage())時出錯。
//this 對象為{CMainDialog}hWnd=???
// First-chance exception in CoolSDIMenu.exe (TESTDLL.DLL): 0xC0000005: Access Violation.
why????????

解决方案 »

  1.   

    怎样从DLL中显示一个对话框首先,在 DLL 运行时,必须保存 DLL 的实例,可以通过 AfxInitExtensionModule。static AFX_EXTENSION_MODULE extensionDLL;extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
    {
       if (dwReason == DLL_PROCESS_ATTACH)
          {
          // Extension DLL one-time initialization
          if (!AfxInitExtensionModule(extensionDLL, hInstance))
             return false;
          }   return(true);
    }    然后,每次使用 DLL 资源时,你必须改变资源的句柄,使其指向 DLL,并保存 exe 的资源,以便以后正确恢复。void get_DLL_resource(void)
    {
       /* this function changes the resource handle to that of the DLL */
       //这个函数改变资源句柄使其指向DLL
       if (resource_counter == 0)
          {
          save_hInstance = AfxGetResourceHandle();
          AfxSetResourceHandle(extensionDLL.hModule);
          }   resource_counter++;
    }    接着你需要其它函数来恢复资源句柄:void reset_DLL_resource(void)
    {
       /* this function restores the resource handle set by
    'get_DLL_resource()' */   if (resource_counter > 0)
          resource_counter--;   if (resource_counter == 0)
          AfxSetResourceHandle(save_hInstance);
    }    接下来一点非常重要,只要有可能就必须恢复资源句柄,否则,你将会遇到许多问题。原因是可执行文件必须重画工具条等等,比如说,如果用户移动 DLL 的对话框,如果资源句柄仍然为 DLL 的资源,程序就崩溃了,我发现最好恢复句柄的时机在对话框的 OnInitDialog() 中,这时对话框的模板等已经读出了。