Hе часто меняются настройки проэктов в Microsoft Visual Studio и, видимо, невозможно каждый раз помнить все детали настроек и их назначение. Я все время "прокалываюсь" на С Run-Time Library в секции Language->Code Generation. В Visual Studio 2005 и Windows XP/Vista ситуация стала еще прикольней - добавил DLL в проэкт, собрал все вместе, проверил - все работает и нет проблем. Проблемы начались, когда программа не запустилась в QA. И вся проблема оказалась именно в Run-Time Library - Microsoft, вложили особый философский смысл в это понятия.
Вот короткое описание как задавать Run-Time Library и чем они отличаются друг от друга:
1. Multi-Threaded (/MT) - это статическая версия C Run-Time Library. Используется и в многопоточных программах. Если она прилинковывается к проекту, то запускаемый файл становится больше - это библиотека становится его частью. Но программу собранную таким способом можно распространят без забот о Microsoft redistributable package.
2. Multi-Threaded Debug (/MTd)- тоже самое, но для отладки программы - выделенная память заволняется предопределенным значением - 0хСС - какая разница.
3. Multi-Threaded DLL (/MD)- это динамическая связь с Run-Time Library, на компьютере пользователя должен быть установлен Redistributable package (msvcrt80.dll for VC2005). Иначе программа просто не побежит, а система будет показывать невразументельные сообщения о неправильной инсталяции программы и предлагать переинсталировать.
4. Multi-Threaded Debug DLL (/MDd)- тоже самое для отладки.
Моя проблема была в Multi-Threaded DLL. Для Visual Studio 2005 SP1 просто подложить недостающие DLL (msvcrt80.dll и что-то еще) недостаточно - нужно инсталировать этот Redistributable package. Не очень атрактивно для комерческой/профессиональной работы - опять таки противоречит EULA видимо. Если спросить: "A за каким вы разработчики Microsoft такую бяку сделали?", они ответят, что такой дезайн позволяет динамически обновлять C Run-Time Library и программа обновляется вместе с ней.
Вспомнил я об этих Run-Time приколах, изменил настройки проэкта на Multi-Threaded. Почему-то даже работает. Хоть и не должно.
Дело в том, что если задано Multi-Threaded, то C Run-Time library (CRT), статически линкуется к DLL-файлам и, если у меня 2 DLL, то я имею и 2 копии CRT. Каждая из них имеет свою кучу (Heap), и контролирует ее независимо. То есть оперировать с памятью совсем не просто - память выделенная в DLL не может быть освобождена в EXE и попытка сделать это разрушает кучу и вызавает крэш программы.
Лучше не сталкиваться с такими проблемамим, а если уж произошло, нужно менять malloc на VirtualAlloc. Я думаю, проще не допускать случае, когда память выделяется в одном модуле, а освобождается в другом.
Вот эти подробности: http://msdn.microsoft.com/en-us/library/abx4dbyh(VS.80).aspx
No comments:
Post a Comment