在x64中第二次RichEdit初始化后崩溃

时间:2010-11-22 06:21:08

标签: windows activex crash 64-bit richedit

根据Using Rich Edit Controls,我以这种方式使用RichEdit:

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

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

它适用于win32但最近我已经构建了x64配置,现在我的控件在页面重新加载后失败。

alt text

我注意到如果这样做:

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

一切正常。

我不希望将此代码投入生产,那么有关于更好的解决方案/解决方法的建议吗?

1 个答案:

答案 0 :(得分:3)

由于报告的故障模块是Richedit20.dll_unloaded,这意味着您正在卸载DLL,而代码仍在使用中。

例如,如果在(完全)释放DLL时仍然打开了一个richedit窗口,只要有任何事情触发对控件的window-proc的调用,就会看到类似的崩溃。这是因为控件的window-proc在卸载的DLL代码中。

多次调用LoadLibrary和FreeLibrary应该是安全的(只要调用平衡掉),所以我怀疑这是问题所在。它可能只是触发问题。另外,问题在于32位版本;你很幸运,从未触发它。

OnDestroy是调用FreeLibrary的错误地方。在WM_DESTROY之后有几个窗口消息被发送到窗口(例如WM_NCDESTROY)。

调用OnDestroy时,子窗口仍然存在。如果richedits是你控制的孩子(而不是控件本身),那么将FreeLibrary移动到OnNcDestroy可能会省你。 (在调用WM_NCDESTROY时,子窗口会被破坏。)不过,我仍然说它不是一个释放库的好地方。

所以你肯定想要移动你的FreeLibrary电话。我会将它和LoadLibrary完全移出控件本身。在创建它们的实例时,拥有加载/释放库的控件是不正常的。相反,在某个地方有一些静态的init / uninit代码,它们可以一劳永逸地加载你需要的库,并在应用程序关闭时释放它们。

(如果您的应用程序很少使用该控件,那么只有当使用该控件的窗口处于活动状态时才加载/释放该库可能是有意义的。但这种情况很少见。通常您最好只保留加载的DLL 。)