Почему сборки .net отличаются для разных архитектур?

Я могу построить свой проект С# для x86 и для x64. Зачем? Я думал, что он генерирует специальный код, который вообще не является платформой.

Ответы

Ответ 1

Во-первых, позвольте мне быть тупым и сказать, что я не знаю всей истории здесь, я собираюсь ответить тем, что, как я думаю, знаю. Я с удовольствием удалю или изменю свой ответ, если кто-нибудь скажет мне, где я ошибаюсь.

Как я понимаю, этот параметр является флагом, в котором говорится, что "сборка должна выполняться в этом типе архитектуры". Это для настроек x86 и x64. Настройка MSIL/.NET просто говорит: "Мне все равно, я могу работать на любом из них, поэтому выберите тот, который будет оптимальным или доступным".

Например, вы можете выполнять вызовы функций API Win32 через P/Invoke, и в этом случае сборка не будет работать на x64, и вы должны указать ее как x86.

Итак, если мое понимание верное, вот как три флага делают сборку (обратите внимание: это основная сборка, сборка программы, которая диктует это, а не каждую отдельную сборку для себя) на разных платформах:

Setting        x86      x64  <-- Platform (CPU/OS)
MSIL/.NET     32-bit   64-bit
x86           32-bit   32-bit
x64           N/A (*)  64-bit

N/A для сборки x64 на x86 означает, что сборка не загружается, и вы получите исключение, если попытаетесь.

Также обратите внимание, что конфликтующие настройки, связанные с x86 и x64, могут привести к сбою вашей программы в той или иной точке. Если основная сборка установлена ​​на x86, она будет работать как 32-разрядный процесс как в 32-разрядной, так и в 64-разрядной операционной системе, и любые попытки загрузки сборок, помеченных как x64, не будут выполнены. Аналогично, если основная сборка установлена ​​на x64, она будет работать только в 64-разрядной операционной системе, и любая попытка загрузки сборки, установленной на x86, не будет выполнена.

Основная исполняемая сборка MSIL будет работать как 32-разрядная в 32-разрядной операционной системе (например, если она была установлена ​​на x86 с указанной выше точкой отказа) и как 64-разрядная в 64-разрядной операционной системе ( например, если он был установлен на x64, с указанной выше точкой отказа.)

Очевидно, Обычно вы хотите перейти с настройкой MSIL, если вы не вызываете сборки, помеченные как что-то конкретное, и пока вы не выполняете P/Invoke, t переносится через 32-битный и 64-разрядный (я понятия не имею, работает ли это, если функции P/Invoke для win-api будут сопоставляться с правильно подобранной dll или нет.)

Поскольку ссылки являются указателями, а указатели сохраняются как собственный x-разрядный адрес на двух платформах, в зависимости от количества ссылок, которые у вас есть, у вас может быть дело против перехода только с MSIL. Однако вы должны убедиться, что это проблема, прежде чем вы вносите изменения в свои настройки.

Ответ 2

Этот флаг важен для EXE файлов. Он решает, выполняется ли 32 или 64-битный процесс. Если вы используете "родные" DLL файлы из вашего .NET-кода, вам нужно следовать архитектуре для этих DLL файлов.

"Любой процессор" в EXE файлах будет выбирать x64, если он доступен.

Ответ 3

Во-первых, установка Platform Target на x86 в вашем проекте .exe очень полезна, когда вы отлаживаете проект в 64-разрядной версии Windows. Отладчик VS2005/8 не поддерживает Edit + Continue в 64-битном коде.

Выбор x86 в вашей сборке релизов - это то, что вы должны делать, если у вас есть зависимость от компонента, который работает только в 32-битном коде. Это не редкость, есть много COM-компонентов, которые никогда не имеют и никогда не будут перенесены на 64-битный неуправляемый код. Один классический пример - механизм базы данных Microsoft Jet.

Выбор x64 очень необычен, очень мало неуправляемого кода, доступного только в 64-битной версии. Примечательно, что вы будете получать предупреждения при сборке сборки, есть несколько сборок .NET Framework, которые содержат неуправляемый код; только 32-разрядные версии доступны в c:\windows\microsoft.net. Вы можете смело игнорировать эти предупреждения, 64-разрядные версии фактически установлены в GAC.

Одна из морщин при выборе x64 заключается в том, что компилятор С# 3.0 выдает двоичный файл, который просит Windows создать поток запуска с размером стека 4 мегабайта вместо 1 мегабайта по умолчанию. Это несколько оправдано, для 64-битного кода требуется больше стека для хранения указателей и возврата адресов.

Наконец, в SDK Windows имеется средство Corflags.exe, доступное для переключения битов сборки после его сборки. Параметр /32BIT + эквивалентен настройке Platform Target на x86. Использование /32BIT- гарантирует, что сборка будет работать в 64-разрядном режиме в 64-разрядной операционной системе. Изменение размера стека по умолчанию возможно с помощью инструмента Editbin.exe.

Ответ 4

Я считаю, что причина, по которой существуют разные цели, связана с размером скалярных типов. Я думаю, что это также влияет на способ обработки COM-объектов.

У меня есть ситуация, когда у меня есть сторонняя библиотека .NET, которая, если она используется в 64-разрядном приложении, не работает при вызове в библиотеку, поэтому я должен ограничиться только 32-разрядным режимом.