Что означает цель «Любой процессор» в Visual Studio?

496

У меня есть путаница, связанная с параметрами сборки платформы .NET в Visual Studio 2008.

Что такое цель компиляции "Any CPU" и какие файлы она генерирует? Я проверил выходной исполняемый файл этой сборки "Any CPU" и обнаружил, что это исполняемые файлы x86 (кто бы не ожидал этого!). Итак, есть ли разница между таргетингом исполняемого файла на x86 и «любым процессором»?

Еще одна вещь, которую я заметил, это то, что управляемые проекты C ++ не имеют этой платформы в качестве опции. Это почему? Означает ли это, что мое подозрение о том, что исполняемые файлы "Any CPU" являются простыми 32-разрядными, верно?

Galets
источник
4
Еще одна вещь, которую следует учитывать при выборе целевой платформы для использования: если целью проекта Startup является Any CPUи вы работаете на 64-битной ОС, вы теряете возможность редактировать и продолжать во время отладки. (Вы эффективно отлаживаете 64-битный процесс). Вы можете сделать целевой проект Startup,x86 чтобы обойти это во время отладки. (Сборки, на которые есть ссылки из стартового проекта, могут продолжать нацеливаться Any CPU.
Кристиан Диаконеску
8
@CristiDiaconescu с VS2013 Редактировать и продолжить теперь возможно
ms007
Я думаю, что здесь следует обратить внимание на то, является ли проект приложением или библиотекой классов, поскольку установка целевого значения битности для последнего может повлиять на его доступность для приложений-потребителей в зависимости от платформы. Я столкнулся с этим с x86библиотекой, используемой AnyCPUприложением, которое я должен был установить, Prefer 32-bitчтобы избежать ошибки загрузки.
SteveCinq

Ответы:

386

AnyCPU сборки будет JIT до 64-битного кода при загрузке в 64-битный процесс и 32 бита при загрузке в 32-разрядный процесс.

Ограничивая процессор, вы бы сказали: сборка использует что-то (что, вероятно, неуправляемо), для чего требуется 32 или 64 бита.

AnthonyWJones
источник
3
Итак, как я могу произвести сборку, которая будет JIT к x64 в C ++?
Галец
50
Проекты C ++ компилируются в нативный код, поэтому JIT-компилятор не задействован ... таким образом, вы не можете делать то, что просите.
cplotts
7
@cplotts: так как @galets задал этот вопрос 3 месяца назад, вряд ли он увидит ваш ответ. Используйте префикс @galets в своем комментарии, аналогично тому, как я здесь, чтобы он получил предупреждение о вашем ответе.
AnthonyWJones
4
@AnthonyWJones В целом вы правы, кроме случаев, когда пользователь является ОП вопроса, как в этом случае, поскольку они будут получать уведомления обо всех комментариях.
Марк Херд
12
@MarkHurd На самом деле, в этом случае ОП не получит уведомление. Операторы не получают уведомления о комментариях к ответам, если они не проверены синтаксисом @. Операторы автоматически получают уведомления только о комментариях, добавленных к их первоначальному вопросу.
RSW
322

Я думаю, что большинство важных вещей было сказано, но я просто решил добавить одну вещь: если вы скомпилируете как Any CPU и работаете на платформе x64, то вы не сможете загружать 32-битные DLL-файлы, потому что ваше приложение не было запущено в WoW64 , но эти DLL-файлы должны запускаться там.

Если вы скомпилируете как x86, то система x64 запустит ваше приложение в WoW64, и вы сможете загружать 32-битные файлы DLL.

Поэтому я думаю, что вам следует выбрать «Любой процессор», если ваши зависимости могут работать в любой среде, но выбрать x86, если у вас есть 32-битные зависимости. Эта статья от Microsoft объясняет это немного:

/ CLRIMAGETYPE (указать тип изображения CLR)

Кстати, эта другая документация Microsoft соглашается с тем, что x86 обычно является более переносимым выбором:

Выбор x86, как правило, является наиболее безопасной конфигурацией для пакета приложения, поскольку он будет работать практически на каждом устройстве. На некоторых устройствах пакет приложения с конфигурацией x86 не запускается, например, Xbox или некоторые устройства IoT Core. Однако для ПК пакет x86 является самым безопасным выбором и обладает наибольшим охватом для развертывания устройства. Значительная часть устройств Windows 10 продолжает работать под управлением версии x86 для Windows.

Пол А Джунгвирт
источник
2
Возможно, вы можете отредактировать свой ответ, чтобы сказать, как можно определить, является ли данная DLL только 32-битной. Насколько я знаю, это должно понять это. Я думаю, что мы надеемся на библиотеки DLL, которые также "Любой процессор", а не только x86.
Дэн W
+1 важное различие. Требовалось использовать 32-битную зависимость (которая не была идентифицирована как таковая). Не удалось выяснить загадочные сообщения об ошибках во время выполнения. На догадку изменил цель процессора, и она работала, но пошел искать «почему». Будет приятно когда-нибудь, когда все будет 64-битным и проблемы несовместимости будут казаться странными, как сейчас 16-битные против 32-битных.
Джеральд Дэвис
2
@GeraldDavis - я согласен. Ирония в том, что нет никакой технологической причины неспособности смешивать 32-битные и 64-битные зависимости (только отсутствие громоздкого слоя в CLR), и я был разочарован в первые дни .NET, когда увидел битовые При развертывании нужно было еще кое-что учесть (учитывая, что это VM / JIT, это дало бы возможность предоставить немного больше добавленной стоимости).
Коденхайм
1
@mrjoltcola: еще хуже, чем то, что Microsoft решила по той причине, что я не могу понять, что записи реестра должны быть разделены на 32-битную и 64-битную вселенную, даже если они управляют такими вещами, как цвета экрана, настройки по умолчанию и т. д.
суперкат
Это ответ, который я искал ... Спасибо!
Мурат из Daminion Software
52

Вот краткий обзор, который объясняет различные цели сборки.

Исходя из моего собственного опыта, если вы хотите создать проект, который будет работать как на платформах x86, так и на платформах x64, и у вас нет каких-либо конкретных оптимизаций для x64, я бы изменил сборку, чтобы специально сказать «x86».

Причина этого заключается в том, что иногда вы можете получить некоторые DLL-файлы, которые сталкиваются, или некоторый код, который приводит к сбою WoW в среде x64. Конкретно указав x86, ОС x64 будет рассматривать приложение как чистое приложение x86 и следить за тем, чтобы все работало гладко.

Dillie-О
источник
37
Что может быть ужасно, если вы пишете для серверной среды и хотите, чтобы ваше приложение могло использовать более 2 ГБ памяти. Вы также отказываетесь от любых JIT-оптимизаций x64, которые могут когда-нибудь случиться.
Остин Харрис
Количество проблем во время выполнения, которые у меня были с компиляциями AnyCPU, - это все оправдание, которое мне нужно, чтобы прекратить использовать его в качестве опции сборки, если кто-то явно не запросил двоичные файлы, которые работают на обоих. У меня не было никого, кто запрашивал двоичные файлы x86 более x64 более 10 лет.
kayleeFrye_onDeck
2
«Конкретно указав x86, ОС x64 будет рассматривать приложение как чистое приложение x86 и следить за тем, чтобы все работало гладко». - Извините, я не согласен. x64 OS по-прежнему будет запускать ваше x86-приложение в WOW64
Мандип Янвю
Это просто плохой совет для тех, кто не совсем понимает, какое влияние это окажет. @AustinHarris дает отличный пример. Представьте себе, что веб-рабочий процесс ограничен всего несколькими гигабайтами оперативной памяти (недавно мне приходилось сталкиваться с этим на производстве).
rgoliveira
47

Прочтите статью Объяснение цели платформы Visual Studio .NET .

Настройка по умолчанию «Любой ЦП» означает, что сборка будет работать на том ЦП, на котором она в данный момент выполняется. Это означает, что он будет работать как 64-разрядный на 64-разрядном компьютере и 32-разрядный на 32-разрядном компьютере. Если сборка вызывается из 64-разрядного приложения, она будет работать как 64-разрядная сборка и т. Д.

Сообщается, что вышеупомянутая ссылка не работает, поэтому есть еще одна статья с похожим объяснением: что на самом деле означает AnyCPU, начиная с .NET 4.5 и Visual Studio 11

DCNYAM
источник
1
Ссылка не работает - идет на припаркованный домен.
Джон Адамс
Я добавил ссылку на вторую статью с похожей информацией. Я оставил первую ссылку на тот случай, если этот домен когда-либо будет активирован.
DCNYAM
46

Кредит на книгу "CLR через C #" , смотрите это:

Введите описание изображения здесь

Иван
источник
3
Это самый точный ответ по состоянию на 06.09.2008 и VS 15.8.0
Райкол Амаро,
39

«Любой ЦП» означает, что при запуске программы .NET Framework выяснит, исходя из разрядности ОС, следует ли запускать вашу программу в 32 или 64 битах.

Существует разница между x86 и любым процессором : в системе x64 ваш исполняемый файл, скомпилированный для X86, будет работать как 32-разрядный исполняемый файл.

Что касается ваших подозрений, просто перейдите в командную строку Visual Studio 2008 и выполните следующее.

dumpbin YourProgram.exe /headers

Он расскажет вам о битности вашей программы, а также многое другое.

AngryHacker
источник
7
Если он встроен в «любой процессор», он будет отображаться как 32-битный в заголовках дампбина.
Кирбинатор
34

Любой процессор означает, что он будет работать на любой платформе. Это потому, что управляемый код похож на Java. Думайте об этом как о скомпилированном байтовом коде, который интерпретируется .NET Framework во время выполнения.

C ++ не имеет этой опции, потому что он скомпилирован в машинный код, который зависит от платформы.

Адам Теген
источник
12
+1 за ответ на одну часть вопроса, которую никто больше не делал (о проектах C ++, не имеющих AnyCPU в качестве опции).
cplotts
C ++ / CLI может быть скомпилирован в код IL без машинного кода (/ clr: pure). Но sizeof (void *) все еще должен быть константой времени компиляции в C ++; поэтому, даже если машинный код не задействован, вы все равно не сможете создать двоичный файл, который будет работать одновременно на 32-битной и 64-битной системах.
Даниэль
5

Я рекомендую прочитать этот пост .

При использовании AnyCPU семантика следующая:

  • Если процесс выполняется в 32-разрядной системе Windows, он выполняется как 32-разрядный процесс. CIL скомпилирован в машинный код x86.
  • Если процесс выполняется в 64-разрядной системе Windows, он выполняется как 32-разрядный процесс. CIL скомпилирован в машинный код x86.
  • Если процесс выполняется в системе ARM Windows, он выполняется как 32-разрядный процесс. CIL скомпилирован в машинный код ARM.
mamczas
источник
8
Только если выбран «Предпочитать 32-битный».
Флориан зима
Что по умолчанию с тех пор, как Visual Studio 11
Moerwald
@ Moerwald Я считаю, что это была ошибка, которая была исправлена. Если вы читаете пост, на который ссылается mamczas, автор пишет: «В текущем пользовательском интерфейсе Visual Studio« Предпочитать 32-битный »неактивен и не отмечен, где на самом деле он включен…»; В моей версии VS (15.8.0) опция по-прежнему неактивна и неактивна, однако она работает, как и ожидалось (флаг 32BITPREF = FALSE в разделе CorFlags скомпилированной сборки)
Raikol Amaro