1

我正在编写的 ActiveX 控件遇到了一个令人困惑的问题 - 有时,Internet Explorer 似乎无法在进程关闭时正确卸载控件。这导致不调用控件实例的析构函数。

该控件是用 C++ 编写的,使用 ATL 并使用 Visual Studio 2005 编译。当用户浏览远离嵌入控件的页面时,始终调用控件实例的析构函数 - 只有在关闭浏览器时才会出现问题。

当我在调试器下运行 IE 时,我没有看到任何异常 - 调试器没有捕获任何异常、访问冲突或断言失败,但问题仍然存在 - 我可以在控件的析构函数中设置断点,它永远不会当我关闭浏览器时点击。

此外,当我加载一个嵌入多个控件实例的简单 HTML 页面时,我看不到问题。该问题仅在从我们的 Web 应用程序实例化控件时才会出现,该应用程序将标签动态插入到网页中 - 当然,不知道是什么导致了这个问题,我不知道这部分信息是否相关,但它似乎表明这可能是一个 IE 问题,因为它依赖于数据。

当我在调试器下运行简单的测试用例时,我可以在控件的析构函数中设置一个断点,并且每次都会命中它。我相信这排除了控件本身的问题(例如,会阻止调用析构函数的错误,例如接口泄漏。)

我使用 IE 6 进行了大部分测试,但我也看到 IE 7 上也出现了问题。我还没有测试过 IE 8。

我现在的工作假设是动态 HTML 代码中的某些内容会导致浏览器泄漏 ActiveX 控件上的界面。到目前为止,我还没有能够在应用程序之外生成一个好的测试用例来重现这个,而且应用程序有点太大而无法制作一个好的测试用例。

我希望有人能够深入了解可能导致这种行为的 IE 错误。顺便说一句,下面提供的答案太笼统了——我正在寻找一组已知会导致这种情况的特定情况。肯定有人以前见过这个。

4

3 回答 3

3

要使用 C++ 调试 COM 中未调用对象 (C++) 析构函数的问题,最好的方法是关注 COM 对象的引用计数如何递增或递减。可能发生的情况是有人将 refcount 增加了太多次,然后没有减少相同的次数。这导致对象未被释放。

您的动态 HTML 可能只是在 IE 中显示了一个错误,而如果您使用静态页面则不会发生这种情况。

如果 IE 中存在错误,诀窍是找出导致错误出现的原因,以及您可以采取哪些措施来诱使 IE 正确释放您的 COM 对象(例如,使 HTML 消失)。

于 2008-09-16T03:18:29.513 回答
0

另一种方法 - 将清理代码添加到您的DllMain函数(如果该函数尚不存在,则添加该函数)。然后不管引用计数(和引用计数错误),当你的 DLL 被卸载时,你可以清理自己:

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

哦,还有一点警告 - 不要花太长时间进行清理 - 如果你这样做了,我不能保证进程关闭无论如何都不会杀死你。

于 2008-10-03T02:46:57.557 回答
0

我有同样的问题,但只在特定的计算机上。这台计算机的 Flash ActiveX 也有问题,关闭选项卡后它仍然存在。我的猜测是问题不在于您的代码。其他电脑有这个问题吗?

于 2008-12-30T13:03:15.537 回答