Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > MS CRT-шный версионный ад


Автор: jonie 22.7.2010, 12:38
Итак, имеем следующую известную проблему: проблему версий CRT Runtime (рассматриваем vs2008) *

*) для тех кто незнает что это такое: версий баблиотек msvcr90.dll не одна и не две, они лежат в windows\WinSxS папке, и винда грузит нужную версию на основании манифеста, указанного в длл-ке либо в app.exe.config файле

Пути ее решения следующие:
1) Поправить в app.exe.config файле, указав конкретный редирект. Например так:
Код

<configuration>

       <windows>

              <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

        <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>

        <bindingRedirect oldVersion="8.0.41204.256-8.0.50727.762" newVersion="8.0.50727.762"/>

      </dependentAssembly>

    </assemblyBinding>

       </windows>

</configuration>
(с) http://blogs.msdn.com/b/nikolad/archive/2007/03/29/a-solution-to-two-references-to-different-versions-of-crt-mfc-atl-in-one-application-manifest-file.aspx

2) найти нужный KB с нужными версиями (вопрос: где взять список того что скачать для конкретной версии CRT?) - поверьте это не такая и простая задача

3) деплоить приложение методом x-copy, беря длл-ки из вашей системы конкретных версий

4) установить 
Код

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1 
в приложении (подробнее: http://msdn.microsoft.com/en-us/library/cc664727%28VS.90%29.aspx) и брать длл-ки из папки Microsoft Visual Studio 9.0\VC\redist\ и опять же деплоить его методом x-copy либо искать KB (вопрос: я не смог найти KB для версии 9.0.30729.4148 , хотя указаное тут http://support.microsoft.com/kb/973552 поставил, там ссылка на бюллетень безопасности)

5) метод "прилинковать статически к CRT" не рассматриваем, ибо мы не любим простые решения, да и есть с ним большие проблемы...

Вопрос: какой метод вы предпочитаете?

UPD: для версии 9.0.30729.4148 вот ссылка http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=2051a0c1-c9b5-4b0a-a8f5-770a549fd78c, KB973552

Автор: Abyx 22.7.2010, 14:50
линкуем статически. все довольны.

Автор: borisbn 22.7.2010, 18:09
Я упаковываю в инсталлятор vcredist_x86.exe и запускаю его из своего инсталлятора
IMHO проще некуда

Автор: jonie 22.7.2010, 22:33
borisbn, прочтите внимательно: версий vcredist не одна и не две. Я вот сегодня буквально попал на интересный баг - у меня было две длл, собранные  в двух версиях CRT... передал я значится std::string* .... которую создал в одном CRT, а убил в другом... получил "по ушам" минут через 5 работы программы....
Конечно, следить никто не отменял...но часто собрать одному разработчику всё нереально, а билд конвееры могут быть настроены черти-как .....



Abyx, попробуйте сделать с 50 DLL и попередавать std-шные объекты и указатели на них между DLL - будет весело (а еще поиграйтесь в нескольких проектах настройками компилятора и линковщика)..... в общем это не спасение, более того, например отладка утечек памяти в подобных длл весьма и весьма нетривиальна (переопределите new и delete для отладки например).....

Автор: borisbn 23.7.2010, 08:10
Цитата(jonie @  22.7.2010,  22:33 Найти цитируемый пост)
передал я значится std::string* .... которую создал в одном CRT, а убил в другом

Цитата(jonie @  22.7.2010,  22:33 Найти цитируемый пост)
попередавать std-шные объекты и указатели на них между DLL


так этого вообще нельзя делать. Ведь понятно же, что объект stl, созданный в одном CRT нельзя даже использовать, а не только удалять, в другом CRT, т.к. stl оговаривает только интерфейс своих объектов, а никак не реализацию ( даже последовательность объявления методов не оговорена, а тем более последовательность и количество членов класса ). Для этого существуют простые типы char * вместо std::string, int * + size_t вместо std::vector. В данном случае даже установка и настройка всех CRT, использовавшихся при сборке exe и dll не спасёт.

Автор: jonie 23.7.2010, 08:34
borisbn, ок. Давайте посмотрим на реализацию log4cxx от апача.. да примером может быть много. Передавать можно, вполне себе, если настройки компиляции и CRT одна и таже. Конкретно в моем случае CRT была тожа одна (9-ая), но разных версий.

Автор: maxim1000 23.7.2010, 08:39
"CRT одна и та же" не то же самое, что одной и той же версии
сам экземпляр должен быть один

если приложение состоит из нескольких модулей, и память, выделенная в одном модуле, освобождается в другом, нужно использовать CRT в виде DLL

ну и, естественно, таскать его с собой в инсталляторе

Автор: jonie 23.7.2010, 09:18
кстати, кому интересно, стоит почитать про winSxS папку тут http://msdn.microsoft.com/en-us/library/aa376307%28VS.85%29.aspx (раздел "Side-by-side Assemblies" и далее)....

maxim1000 ну да, я немного не так сказал - у меня получилось загрузить два инстанса crt9 и произошел сбой.

Автор: borisbn 23.7.2010, 10:58
jonie, у нас несколько довольно крупных проектов. Так уж получилось, что одни части сделаны на Builder'е 5.0, другие - на MSVC 2005, другие - на MSVC 2008.
У нас принято жёсткие правила:
1. Передавать из exe в dll и обратно только простые типы. Никаких stl, vcl, qt-объектов.
2. Всегда явно в коде указывать выравнивание ( #pragma pack( push, 4 ) ) и calling conventions функций ( __stdcall или __cdecl )
3. Удаляет память ( объекты ) тот, кто создал

И проблем с CRT никаких не было.

Автор: Dem_max 23.7.2010, 11:47
borisbn правильный подход

Автор: Abyx 23.7.2010, 11:56
а еще можно бросить этот ####й C++ и писать на C#

Автор: Dem_max 23.7.2010, 12:00
ага и в дистрибутив включать .NET Framework

Автор: jonie 23.7.2010, 12:48
borisbn, в указанных тобой случаях это да, необходимо. Но зачастую есть исключения - это не хорошо и не плохо - это нормально.

Автор: VSB 7.8.2010, 17:57
Dem_max
2010 год уже к концу идет, пора бросить XP а в висте и 7 уже есть .NET из коробки (правда в 7 только до 3,5 версии).

Автор: Dem_max 7.8.2010, 18:40
Цитата

2010 год уже к концу идет, пора бросить XP а в висте и 7 уже есть .NET из коробки (правда в 7 только до 3,5 версии).

Это не правильный подход.
Eсли что напомню, на сей момент до сих пор работают программы под MS-DOS, собственно говоря WinXP еще долго будет на плаву.

Автор: Alca 7.8.2010, 18:40
Цитата

а еще можно бросить этот ####й C++ и писать на C#

и кодить тока под винду

Автор: Abyx 7.8.2010, 22:49
Alca, а могут быть проблемы с MS CRT под никсами?)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)