崩潰

2010-11-22 193 views
0

根據Using Rich Edit Controls我在這樣的方式使用的RichEdit:崩潰

MyControl::OnCreate() 
{ 
    handle = LoadLibrary(_T("Riched20.dll")); 
} 

MyControl::OnDestroy() 
{ 
    FreeLibrary(handle); 
} 

它工作正常,爲Win32,但頁面重載之後最近我已經建立了64配置,現在我的控制失敗。

alt text

我已經注意到,如果做到這一點:

MyControl::OnCreate() 
{ 
    handle = LoadLibrary(_T("Riched20.dll")); 
    FreeLibrary(handle); 
    handle = LoadLibrary(_T("Riched20.dll")); 
} 

一切工作正常。

我不希望將此代碼投入生產,因此,有沒有關於更好的解決方案/解決方法的建議?

回答

3

由於報告的故障模塊是Richedit20.dll_unloaded,這意味着您正在卸載DLL,而其中的代碼仍在使用中。

例如,如果在(完全)釋放該DLL時仍然打開一個RichEdit窗口,只要有任何事件觸發了該控件的window-proc調用就可以看到類似的崩潰。這是因爲控件的window-proc在卸載的DLL代碼中。

多次調用LoadLibrary和FreeLibrary應該是安全的(只要呼叫平衡),所以我懷疑這是問題所在。這可能只是觸發問題。另外,問題出現在32位版本中;你很幸運,從來沒有觸發過它。

OnDestroy是調用FreeLibrary的錯誤地方。 WM_DESTROY(例如WM_NCDESTROY)後有幾個窗口消息被髮送到窗口。

當調用OnDestroy時,子窗口仍然存在。如果富有的人是你控制的孩子(而不是控制本身),那麼將FreeLibrary移動到OnNcDestroy可能會節省你。 (子窗口在WM_NCDESTROY被調用時會被銷燬)。但是,我仍然認爲它不是釋放庫的好地方。

所以你一定要移動FreeLibrary調用。我會將它和LoadLibrary完全移出控件本身。每當創建它們的實例時,具有加載/釋放庫的控件是不正常的。相反,有一些靜態的init/uninit代碼會加載你需要的庫,並在應用程序關閉時釋放它們。 (如果你的應用程序很少使用控件,那麼只有當使用控件的窗口處於活動狀態時,才能加載/釋放庫是有意義的,但是這種情況很少發生,通常你最好離開DLL加載。)

+0

感謝您的快速回復。我已將代碼移至DllMain,現在一切正常。再次感謝。 – Eugene 2010-11-22 06:59:22

+1

@Eugene樂意幫忙!順便說一句,在DllMain中調用LoadLibrary也會導致問題。請參閱:http://blogs.msdn.com/b/larryosterman/archive/2004/04/23/118979.aspx - 理想情況下,您可以將此代碼放入您的DLL的Init函數中,父應用程序在加載後調用它你的DLL。 (這也是註冊控件的窗口類的正確位置。)但是,如果您無法控制父應用程序,那麼事情會變得棘手。 :( – 2010-11-22 07:38:56