sysexit Загрузчик блокирует статически прилинкованные модуля, загружая в счётчик загрузок модуля маркер, проверяя который лодер блокирует попытки выгрузки. Легальный способ обойти это - поиск описателя(LdrFindEntryForAddress() etc.) и правка счётчика загрузок.
Тут еще нашел некоторую информацию (http://wasm.ru/forum/viewtopic.php?id=32253), user32.dll она же динамическая библиотека... Как тогда понять какая динамическая а какая нет?
sysexit Модуля подгружаемые автоматически системным загрузчиком на основе импорта модуля это статическая линковка. Остальные способы загрузки это динамическая линковка.
Если в импорте exe есть user32.dll статическая линковка -- dll не выгрузится. Если его там нету, и в самой программе сделать так: invoke LoadLibraryA, "user32.dll" invoke FreeLibrary,EAX То Dll опять же не выгрузится, или это тоже статическая линковка?
sysexit Выгрузится, почему же нет. Просто некоторые модуля могут увеличивать счётчик загрузок, изза чего одного вызова FreeLibrary() будет не достаточно.
http://www.sendspace.com/file/gg2q7k Вот тут динамически загружается user32.dll и в цикле крутится FreeLibrary() в связке с GetModuleHanldeA(). Сколько нужно итераций что бы выгрузилась данамически подгруженая dll, 1000? Миллион?
sysexit Ну на чистой оси не виснет. Мало ли какой гуан у вас установлен. В конце концов отладчик откройте и посмотрите.
Я уже смотрел в отладчике. Виснет означает что user32.dll не выгружается, и поле после 11 итераций обнуления становится 0xFFFF. На другом компьютере тоже самое. А ось у меня грязная только на user32.dll а когда с comctl32.dll работаю, она чистая, раз все выгружается?
sysexit У меня XPSP3(nt 5.1.2600.5512) и всё выгружается на второй итерации. С user32 обычно куча модулей загружается, из них могут быть сторонние, которые запретят выгрузку или даже вобще нотификацию модулей загрузчиком. Вы не должны выгружать то, что явно не загрузили, а только уменьшить счётчик загрузок.
Сказано верно, но еще продолжу: Если написать Код (Text): int Main (....){ MessageBox(....); return 0; } то линкер ругнется на MessageBox, исправить код, значит добавить Код (Text): #include "Windows.h" - теперь запустишь и все заработает, НО уже есть статическая линковка Альтернатива - не писать #include "Windows.h", а ипользовать след код Код (Text): #define UNICODE typedef int (MessageBoxProc)(HWND, LPCTSTR, LPCTSTR, UINT); int Main (....){ // подгрузим DLL (явная динамическая загрузка) hDll = ::LoadLibrary(_T("User32")); // для MessageBox MessageBoxProc* MessageBox; if (hDll) MessageBox = (MessageBoxProc*)GetProcAddress(hDll, "MessageBoxW"); // UNICODE определен. else return false; // Вызовем MessageBox int nRes = (*MessageBox)(NULL, _T("Текст сообщения"), _T("Заголовок"), 0); // а теперь выгрузим User32.dll FreeLibrary(hDll); } Но есть одно НО, таким способом нужно запускать все функции из User32.dll которые ты используешь в своей проге И ТОЛЬКО ТОГДА у тебя будет ТОЛЬКО ДИНАМИЧЕСКАЯ ЗАГРУЗКА DLL и вызвав FreeLibrary ты уменьшишь счетчик и "выбросишь" DLL из адресного пространства тек процесса
ну во первыз речь идет о выгрузке DLL а не освобождении памяти из MSDN { VirtualFree Function Releases, decommits, or releases and decommits a region of pages within the virtual address space of the calling process. To free memory allocated in another process by the VirtualAllocEx function, use the VirtualFreeEx function. } Во вторых а стараюсь писать по принципу: не я выделял память и не мне освобождать (за исключением того если докуменнтировано требование освободить) не я загружал и не мне выгружать. в третьих я ПРЕДЛОЖИЛ вариант использования динамической загрузки, в результате которой корректно выгружается DLL без "последствий" для процесса.