Совместимость с набором инструментов vs2012

В моем VS2012 у меня есть 4 набора инструментов: v90, v100, v110 и v110_xp. Я провел простой тест с двумя проектами testlib (статическая библиотека) и testexe (консольное приложение). Интерфейс представлял собой всего одну функцию с сигнатурой void test(). Результаты, достижения:

  • testlib (v90), testexe (любой, кроме v90) -> не связывается
  • testlib(v100), testexe(v110 или v110_xp) -> делает ссылку

Однако мне показалось несколько странным, что v100 и v110 могут быть связаны, поэтому я попытался немного усложнить сценарий. Теперь мой метод выглядит так: std::map<std::string, std::string> test(const std::string& arg). Как и ожидалось, testlib(v100) и testexe(v110) не связаны (mismatch detected for '_MSC_VER').

Но все же testlib (v110) и testexe (v110_xp) связаны, и полученный exe-файл работает на Windows XP. Это случайно или это поддерживаемый сценарий? Если это случайно, то приветствуется пример кода, который использует только функции, доступные в v110_xp, и нарушает эту совместимость. Мне интересно, следует ли мне развернуть две версии моей библиотеки для моих клиентов или подойдет только та, которая скомпилирована с v110.


person Tomasz Grobelny    schedule 20.01.2013    source источник
comment
Вы пропустили CTP за ноябрь 2012 года, который, по крайней мере, пытается приблизиться к реализации стандарта C++11 (вы знаете, что это сложно; спросите Herb =P).   -  person WhozCraig    schedule 20.01.2013
comment
Похоже, вы выставляете стандартные объекты из своей библиотеки (например, std::string и т. д.) и надеетесь, что они «просто работают» с клиентами указанной библиотеки, построенной на другом наборе инструментов. Даже если они зависят от поставщика (в данном случае все от MS), разница только в алгоритмах изменения имени не гарантируется, а тем более полный ABI для любой реализации их кода на основе библиотеки. Несвязанный: я не знал, что в 2012 году появился набор инструментов v9, кстати. У вас есть vs2008 на той же машине?   -  person WhozCraig    schedule 20.01.2013
comment
Да, на этой машине у меня установлены vs2008, vs2010 и vs2012 - введение моего вопроса могло немного ввести в заблуждение.   -  person Tomasz Grobelny    schedule 20.01.2013


Ответы (3)


Слово «набор инструментов» немного неправильно для описания различий между v110 и v110_xp. Вы все еще используете те же инструменты сборки. И у вас все та же версия ЭЛТ. Что-то, что вы можете увидеть, сравнив то, что вы видите в списке Debug + Windows + Module загруженной DLL между двумя сборками. Обратите внимание на имя и расположение msvcr110.dll.

Фактически CRT был обновлен Update 1, теперь он поддерживает как XP, так и более новые версии Windows. Это работает путем динамической привязки к более поздним функциям winapi во время выполнения, используя GetProcAddress(), ковыляя, если он не может их найти, когда вы работаете в XP.

Отличие в том, что вы получили другую версию Windows SDK. Последний, который был еще совместим с XP, версии 7.1. Вы найдете его в папке C:\Program Files (x86)\Microsoft SDK\Windows\v7.1A. При сборке с помощью набора инструментов v110 вы будете использовать включаемые файлы SDK и файлы библиотек, хранящиеся в папке C:\Program Files (x86)\Windows Kits\8.0.

Конкретные изменения при использовании v110_xp видны при поиске этой строки в каталоге c:\program files (x86)\msbuild:

  • каталоги для файлов include и lib и т. д. заменяются путями Windows 7.1 SDK.
  • добавлен символ препроцессора _USING_V110_SDK71_, который иначе нигде не используется
  • Параметр компоновщика /SUBSYSTEM изменен, чтобы требовать только версию Windows 5.02, номер версии XP.

Короче говоря, смешивание модулей, которые были созданы с использованием наборов инструментов v110 и v110_xp, не является проблемой.

person Hans Passant    schedule 20.01.2013
comment
Я ничего не говорил о CRT или распределении памяти. Я упомянул об импорте/экспорте классов и взаимозаменяемом использовании классов (например, векторов) в разных DLL. Предположим, что вектор‹int› выделен в A.DLL и передается в B.DLL. Обе DLL используют разные компиляторы/компоновщики. Это очень известная, волнующая и, возможно, неразрешимая проблема! - person Ajay; 20.01.2013
comment
Вот почему подумал, что стоит упомянуть об этом. Эта неразрешимая проблема на самом деле решена ;) - person Hans Passant; 20.01.2013
comment
Я не согласен с этим. Предположим, у меня есть DLL, созданная с использованием VS2008, которая принимает map<CString, long>. Теперь я вызываю его из встроенной DLL VS2010/12 - как вы можете быть уверены, что это не вызовет никаких проблем? Дело НЕ в выделении памяти, а в самом объекте. - person Ajay; 20.01.2013
comment
Нет, конечно, это исправление не может работать задним числом. Он не может подключиться к старой DLL и заменить CRT. Он работает для сборок VS2012 и выше, в случае с OP. - person Hans Passant; 20.01.2013
comment
@HansPassant, извини. Я все равно с тобой не согласен! Я вовсе не имею в виду распределение памяти. Просто CStringA НЕ CStringW, и, следовательно, CString будет различаться в разных сборках. Безопасная версия STL не то же самое, что небезопасная. Понимаешь, что я говорю!? - person Ajay; 20.01.2013
comment
@HansPassant, вы пришли к выводу, что смешивание модулей, созданных с использованием наборов инструментов v110 и v110_xp, не является проблемой. Что происходит, когда я создаю свое приложение с помощью v110_xp и статически связываю его с библиотеками boost, созданными с использованием v110, — будет ли оно работать под WinXP? (Или другой вопрос: как собрать библиотеки boost с помощью v110_xp? Похоже, этот новый набор инструментов еще не поддерживается boost.build — или у вас есть решение для этого?) - person Robert Hegner; 29.01.2013
comment
@RobertHegner: testlib (v110) и testexe (v110_xp) связаны, и полученный exe-файл работает в Windows XP - не уверен насчет повышения, но есть шанс, что он будет работать нормально. - person Tomasz Grobelny; 29.01.2013
comment
@TomaszGrobelny да в вашем простом тестовом сценарии. Но у меня все еще есть ваше первоначальное беспокойство - это случайно или это поддерживаемый сценарий? Ханс Пассант очень ясно говорит о создании сочетания v110 и v110_xp (тот же компилятор, тот же компоновщик, та же CRT, так что никаких проблем во время сборки). Но в любом случае такая комбинация работает под WinXP? Что произойдет, если testlib(v110) использует некоторые функции WinAPI версии 8.0? Получу ли я какое-то значимое исключение или он просто молча вылетит? Я не очень уверен в использовании boost(v110) с exe(v110_xp) в рабочей среде... - person Robert Hegner; 29.01.2013
comment
Никогда не существует обходного пути для неправильной установки макроса _WIN32_WINNT. Вы должны выбрать версию Windows, которую хотите поддерживать. Если это XP, вам нужно установить его на 0x0501, чтобы вы не могли случайно использовать функции winapi, которые доступны только в более поздних версиях Windows. Это совершенно не связано с набором инструментов, это общее требование. - person Hans Passant; 29.01.2013

Смешивание v110_xp исполняемых файлов и v110 библиотек официально не поддерживается.

Обсудив этот вопрос отдельно с Microsoft, они ответили на следующие вопросы:

В1. Может ли приложение, использующее эти библиотеки (v110) и созданное с помощью набора инструментов v110_xp, правильно работать на компьютере с Windows XP?

Только исполняемый файл, созданный с помощью набора инструментов v110_xp, может правильно работать на компьютере с Windows XP. В результате, если приложение должно правильно работать на компьютере с Windows XP, вам нужно будет убедиться, что ваш проект переключен с набора инструментов v110 по умолчанию на недавно представленный набор инструментов v110_xp на страницах свойств вашего проекта, включая исполняемый файл и библиотеки DLL, если есть какие-либо.

Вопрос 2. Нужно ли нам выпускать еще одну версию этих библиотек, созданную с помощью набора инструментов v110_xp?

Я думаю, это зависит от того, на какой платформе вам нужно развернуть приложение. Если ваш план развертывания включает компьютеры с Windows XP, необходимо выпустить новую версию исполняемого файла/библиотек DLL, созданных с помощью набора инструментов v110_xp. Однако, учитывая, что одни и те же исполняемые файлы/DLL, созданные с помощью набора инструментов v110_xp, также будут работать в Vista и более поздних версиях, я предлагаю вам просто сохранить одну версию исполняемых файлов/DLL, созданных с помощью набора инструментов v110_xp, и она может работать на всех других платформах. Когда Windows XP больше не входит в ваш план развертывания, вы можете преобразовать весь исполняемый файл/DLL для пересборки с помощью набора инструментов v110. Конечно, было бы хорошо, если бы вы могли поддерживать две версии исполняемых файлов/DLL одновременно, если вы хотите работать с Windows XP и другой системой отдельно.

Вопрос 3. Поддерживает ли корпорация Майкрософт библиотеки, созданные с помощью набора инструментов v110 в Windows XP?

Ответ - нет. Все должно быть построено в режиме v110_xp, если вы хотите правильно запустить приложение в Windows XP.

person Steve-o    schedule 10.04.2013
comment
Имеет смысл для DLL. Но исходный вопрос был о статических библиотеках. - person Tomasz Grobelny; 12.04.2013
comment
Как указал HansPassant: у вас все еще та же версия ЭЛТ. Я пытаюсь подчеркнуть, что, на мой взгляд, два ответа не противоречат друг другу и оба верны. За исключением того, что ответ HansPassant более актуален для вопроса (но все же спасибо, что поделились этим). - person Tomasz Grobelny; 14.04.2013
comment
@TomaszGrobelny Microsoft отвечает как для общих, так и для статических библиотек. Статические библиотеки в Windows нацелены на конкретный CRT, так что вы все равно получите беспорядок. - person Steve-o; 15.04.2013
comment
У меня есть exe, который не работает на Windows XP. Могу ли я обнаружить, что он не был скомпилирован в режиме v110_xp или что-то в этом роде? - person Tomas Kubes; 09.04.2014

Пожалуйста, не смешивайте DLL, имеющие/экспортирующие классы, с разными версиями Visual Studio (даже с незначительными различиями версий). STL и MFC имеют классы, построенные поверх шаблонов (сам классы могут не быть шаблонными для пользователя), что предотвращает связывание и/или компиляцию между разными версиями.

Простым примером может быть CString: статическое и динамическое связывание с MFC будет иметь разные реализации CString. Unicode и ANSI CString также различаются. Другим примером является сама STL: сборка отладки vector отличается от сборки выпуска vector. Кроме того, в случае коллекций STL настройки компилятора также изменят размер/реализацию контейнера (например, vector, list).

Таким образом, лучше не импортировать классы/функции экспорта, имеющие классы такого типа в качестве параметров. Даже не передавайте их непрозрачным способом (например, поверх указателя на пустоту).

person Ajay    schedule 20.01.2013
comment
Хорошо, я понимаю, что смешивание разных версий невозможно (как показано выше). Но сейчас я использую только последнюю версию VS2012 с ее специфическими наборами инструментов (v110 и v110_xp). Могу ли я смешивать эти два набора инструментов? - person Tomasz Grobelny; 20.01.2013