2010-11-22 2 views
0

По Using Rich Edit Controls я использую RichEdit таким образом:Краша после второй инициализации RichEdit в 64

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")); 
} 

все работает отлично.

Я не хочу вводить этот код в производство, поэтому есть предложения по улучшению решения/обходного пути?

ответ

3

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

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

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

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

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

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

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

+0

Благодарим за быстрый ответ. Я переместил код в DllMain, и теперь все работает отлично. Еще раз спасибо. – Eugene

+1

@ Юджин Счастлив помочь! Кстати, вызов LoadLibrary в DllMain может также вызвать проблемы. См. Здесь: http://blogs.msdn.com/b/larryosterman/archive/2004/04/23/118979.aspx - В идеале вы должны поместить этот код в функцию Init вашей DLL, которую родительское приложение вызывает после загрузки вашей DLL. (Это правильное место для регистрации класса окна управления тоже). Если у вас нет контроля над родительским приложением, все может оказаться сложным. :( –

Смежные вопросы