2008-09-15 88 views
1

我遇到了一個令人困惑的問題,我正在寫一個ActiveX控件 - 有時,Internet Explorer似乎無法正確卸載過程關閉控件。這導致控件實例的析構函數不被調用。在什麼情況下Internet Explorer無法正確卸載ActiveX控件?

該控件是用C++編寫的,使用ATL並使用Visual Studio 2005編譯。控件實例的析構函數總是在用戶瀏覽控件所嵌入的頁面時調用 - 問題只發生在瀏覽器關閉。當我在調試器下運行IE時,我沒有看到任何異常 - 調試器沒有發現任何異常,訪問衝突或斷言失敗,但問題仍然存在 - 我可以在控件中設置斷點析構函數,當我關閉瀏覽器時它從來沒有被打。

此外,當我加載一個嵌入控件的多個實例的簡單HTML頁面時,我沒有看到問題。這個問題似乎只發生在控件從我們的web應用程序實例化的時候,它會動態地將標籤插入到網頁中 - 當然,不知道是什麼原因導致了這個問題,我不知道這一點信息是否相關,但它似乎表明這可能是一個IE問題,因爲它依賴於數據。

當我在調試器下運行簡單的測試用例時,我可以在控件的析構函數中設置一個斷點,並且每次都會觸發它。我相信這排除了控制本身的問題(比如說,一個會阻止析構函數被稱爲接口泄漏的錯誤)。

我使用IE 6測試了大部分測試,但我在IE 7上也發現問題。我還沒有測試過IE 8

我現在的工作假設是動態HTML代碼中有一些東西導致瀏覽器泄漏ActiveX控件上的一個接口。到目前爲止,我還沒有能夠生成一個能夠在應用程序之外重現此類應用程序的好測試用例,而且該應用程序有點太大而無法做出好的測試用例。

我希望有人能夠提供洞察,可能會導致這種行爲的IE錯誤。順便提一下,下面提供的答案太籠統了 - 我正在尋找一系列已知導致此情況的具體情況。當然有人在那裏見過這個。

回答

3

要調試COM中C++中未調用對象(C++)析構函數的問題,最好的方法是關注COM對象的引用計數如何遞增或遞減。可能發生的情況是,有人正在多次增加該次數,然後不會遞減相同的次數。這導致對象不被釋放。

您的動態HTML可能只是簡單地在IE中顯示一個錯誤,如果您使用靜態頁面,則不會發生這種錯誤。

如果IE中存在一個錯誤,訣竅就是找出導致錯誤出現的原因,以及如何欺騙IE以正確釋放COM對象(例如,使HTML消失)。

+0

感謝您的建議。動態的HTML代碼是足夠多毛的,沒有人確定它是如何工作的,我試圖解開它足以創建一個再現問題的測試用例迄今爲止失敗了。 – 2008-09-16 23:15:05

0

另一種方法 - 將清理代碼添加到您的DllMain函數(如果該函數尚不存在,則添加該函數)。然後,無論引用計數(和引用計數錯誤),當你的DLL卸載可以清理自己了:

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) { 
    if (dwReason == DLL_PROCESS_DETACH) { 
     CleanUpAnyObjectsStillAlive(); 
    } 
} 

哦,提醒一句 - 不要花太長的時間做你清理 - 如果你做,我不能保證過程關機不會殺死你。

+0

你知道在一個用MFC編寫的控件中不能這樣做,對吧? – 2008-10-06 15:08:24

+0

爲什麼?我不是MFC專家,但我不明白像MFC這樣的庫如果想要包含一個庫,可以阻止*提供自己的DllMain。你的意思是MFC控件不提供清理它們的方法嗎?如果是這樣的話就會起鬨。 – Bruce 2008-10-08 06:32:18

0

我有同樣的問題,但只在特定的計算機上。 此計算機還存在Flash ActiveX問題,該問題在關閉該選項卡後仍保持有效狀態。 我的猜測是問題不在於你的代碼。你在其他電腦上有這個問題嗎?

相關問題