0

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

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

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

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

替代文字

我注意到如果这样做:

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

一切正常。

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

4

1 回答 1

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 完全移出控件本身。每当创建它们的实例时,控制哪些加载/释放库是不正常的。取而代之的是,在某处有一些静态的初始化/初始化代码,它可以一次性加载您需要的库,并在应用程序关闭时释放它们。

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

于 2010-11-22T06:33:32.967 回答