Сбой после второй инициализации RichEdit в x64 - PullRequest
0 голосов
/ 22 ноября 2010

Согласно Использование 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 Ответ

3 голосов
/ 22 ноября 2010

Поскольку указанный модуль неисправности - Richedit20.dll_unloaded, это означает, что вы выгружаете DLL, пока код из нее все еще используется.

Например, если у вас по-прежнему открыто окно richedit, когда вы (полностью)Освободив DLL, вы можете увидеть такие сбои, как только что-нибудь вызовет вызов в window-proc элемента управления.Это связано с тем, что window-proc элемента управления был внутри выгруженного кода DLL.

Безопасно вызывать LoadLibrary и FreeLibrary несколько раз (при условии, что вызовы уравновешиваются), поэтому я сомневаюсь, что это проблема.Это может быть причиной проблемы.Кроме того, проблема была в 32-битных сборках;вам просто повезло, и вы никогда не вызывали его.

OnDestroy - неподходящее место для вызова FreeLibrary. Есть несколько оконных сообщений, которые отправляются окну после WM_DESTROY (например, WM_NCDESTROY).

Дочерние окна также все еще существуют при вызове OnDestroy.Если средства являются дочерними элементами вашего элемента управления (а не самого элемента управления), перемещение FreeLibrary в OnNcDestroy может спасти вас.(Дочерние окна разрушаются к тому времени, когда вызывается WM_NCDESTROY.) Однако я все же сказал бы, что это не очень хорошее место для освобождения библиотеки.

Так что вы определенно хотите переместить вызов FreeLibrary.Я бы переместил и его, и LoadLibrary полностью из самого элемента управления.Нормально иметь элементы управления, которые загружают / освобождают библиотеки, когда создается их экземпляр.Вместо этого, где-нибудь есть статический код init / uninit, который загружает нужные вам библиотеки раз и навсегда и освобождает их при завершении работы приложения.

(Если ваше приложение использует элемент управления очень редко, тогда может иметь смыслзагружать / освобождать библиотеку только тогда, когда окна, использующие элемент управления, активны. Однако такая ситуация встречается редко. Обычно лучше просто оставить DLL загруженной.)

...