|
|
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
Помнится спрашивал я где-то на форуме по поводу корректного освобождения библиотек при загрузке через LoadLibrary и фиксации BoundsChecker'ом (а точнее Error Detection) неосвобожденного ресурса при их освобождении через FreeLibrary, в конце их использования, но мне так никто не ответил отчего это так происходит. Искал, искал, но что-то не нашел, поэтому поднял еще одну тему. Кратко напомню о чем речь. Вот такой абстрактный код Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. вызывает ошибку при проверке в BoundsChecker'e. Последний утверждает что библиотека осталась невыгруженной. Причем если ставить брэки, то функция FreeLibrary срабатывает, но результат остается прежним. Что я только не делал и какие попытки не предпринимал, результата так и не добился, BC упорно утверждает что библиотека не освобождена. Сегодня совершенно случайно я наткнулся на функцию FreeLibraryAndExitThread, которая совершила маленькое чудо, избавив меня от этой проблемы, но все же тень сомнения осталась, насколько корректно будет заменить ею FreeLibrary и на чем это может сказаться? Получается что загрузив библиотеку мы создаем еще один поток и для того чтобы корректно завершить использование библиотеки недостаточно, как утверждает msdn, просто вызвать FreeLibrary, нужно еще и поток прибить. Я понимаю что эту "ошибку" вполне разрулит ядро ОС, когда приложение завершится, но все же хотелось понять отчего так... -------------------------------------------------------------- [не претендую на уникальность] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2007, 12:44:39 |
|
||
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
RichterЯвная выгрузка DLL Если необходимость в DLL отпадает, ее можно выгрузить из адресного пространства процесса, вызвав функцию. Код: plaintext Вы должны передать в FreeLibrary значение типа HINSTANCE, которое идентифицирует выгружаемую DLL. Это значение Вы получаете после вызова LoadLibrary(Ex). DLL можно выгрузить и с помощью другой функции: Код: plaintext Она реализована в Kernel32.dll так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. На первый взгляд, в ней нет ничего особенного, и Вы, наверное, удивляетесь, с чего это Microsoft решила ее написать. Но представьте такой сценарий. Вы пишете DLL, которая при первом отображении на адресное пространство процесса создает поток. Последний, закончив свою работу, отключает DLL от адресного пространства процесса и завершается, вызывая сначала FreeLibrary, а потом ExttThread. Если поток станет сам вызывать FreeLibrary и ExitThread, возникнет очень серьезная проблема: FreeI.ibrary тут же отключит DLL от адресного пространства процесса. После возврата из FreeLibrary код, содержащий вызов ExttThread, окажется недоступен, и поток попытается выполнить не известно что. Это приведет к нарушению доступа и завершению всего процесса! С другой стороны, если поток обратится к FreeLibraryAndExitThread, она вызовет FreeLibrary, и та сразу же отключит DLL, Но следующая исполняемая инструкция находится в KerneI32.dlI, а не в только что отключенной DLL. Значит, поток сможет продолжить выполнение и вызвать ExitThread, которая корректно завершит его, не возвращая управления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2007, 13:23:54 |
|
||
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
о да, великий Рихтер знает все, жаль я не он... -------------------------------------------------------------- [не претендую на уникальность] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2007, 13:28:06 |
|
||
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
Tubrik RichterЕсли поток станет сам вызывать FreeLibrary и ExitThread, возникнет очень серьезная проблема:Угу... и при этом в описании DllMain несколько раз говорится: Не надо выгружать самого себя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2007, 18:30:03 |
|
||
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
а как правильно? -------------------------------------------------------------- [не претендую на уникальность] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2007, 18:40:08 |
|
||
|
спешу делиться опытом
|
|||
|---|---|---|---|
|
#18+
Cerebrumа как правильно?Что как правильно? Как правильно завершать DLL? Документацию открывать не пробовал? Читай тут: http://msdn2.microsoft.com/en-us/library/ms682583.aspx Да и вообще, вам в школе инкапсуляцию объясняли? DLL это тот же класс. У него имеются свои методы, и свои внутренние объекты. Функция DllMain является конструктором и деструктором этого класса. Объект сам себя не уничтожает, в своем деструкторе он уничтожает свои внутренние объекты/нити, но никогда сам себя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2007, 18:47:10 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=34751860&tid=2028311]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
179ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
| others: | 217ms |
| total: | 478ms |

| 0 / 0 |
