Проблемы с процессорной архитектурой (x86 против любого процессора)
У меня есть библиотека, которая построена для x86. При компиляции.net проектов в "любом процессоре", который ссылается на сборку, я получаю следующее предупреждение компилятора:
"There was a mismatch between the processor architecture of the project being built "MSIL" and
the processor architecture of the reference "xxx", processorArchitecture=MSIL", "x86". This
mismatch may cause runtime failures. Please consider changing the targeted processor
achitecture of your project through the Configuration Manager..."
У меня есть два проекта. Проекты A и B. Оба проекта.net C# visual studio (2013). Проект A - это служба Windows, проект B - это простое приложение для создания форм Windows. Они оба используют общую библиотеку (также любой процессор), которая снова (иногда) использует библиотеку x86.
Проект A(Служба Windows,AnyCpu) ->CommonLibrary(AnyCPU)->UtilityLibrary(x86)
Проект B(WinForms, AnyCpu) ->CommonLibrary(AnyCPU)->UtilityLibrary(x86)
В проекте A я получаю ошибку во время выполнения при использовании UtilityLibrary. Но не в Project B. Ошибка времени выполнения в Project A устраняется, когда UtilityLibrary встроен в "Any Cpu" или Project A встроен в x86, поэтому я знаю, что это связано с этим.
У меня вопрос: в каких случаях возникают ошибки времени использования библиотек, специфичных для архитектуры?
UtilityLibrary - это часть недавнего выпуска программного обеспечения, а CommonLibrary - это API, также часть выпуска программного обеспечения. Я пытаюсь определить последствия этого. В будущих выпусках UtilityLibrary будет построен для AnyCpu, так как нет причин для этого быть X86.
2 ответа
При работе на 64-битной машине стандартным поведением является запуск AnyCPU
исполняемый в 64-битном процессе, а не в 32-битном. Сборка с пометкой x86
не удастся загрузить в 64-битном процессе..NET Framework предполагает, что в нем есть что-то, что зависит от архитектуры, и что лучше сообщать о проблеме заранее, чем аварийно завершать работу или делать неправильные действия при выполнении операции, специфичной для архитектуры.
Инструменты сборки предупреждают вас, что это произойдет, если вы запустите его в этом сценарии.
Если вы уверены, что UtilityLibrary не содержит какой-либо специфичный для процессора код или зависит от чего-либо, что доступно только как 32-битная библиотека (например, ядро базы данных JET), вы можете избежать перекомпиляции, изменив заголовки, используя CorFlags.exe. Команда, которая вам нужна:
corflags <path-to-assembly> /32bit-
В.NET 4.5 появилась новая опция: "Предпочитать 32-битный". Для компилятора C# эта опция /platform:anycpu32bitpreferred
, Исполняемый файл, помеченный этим значением, будет выполняться в 32-разрядном процессе на 64-разрядной машине, если доступна 32-разрядная среда выполнения. В Windows 7/Server 2008 R2 и более поздних версиях фактически можно удалить слой WOW64, который позволяет запускать 32-разрядные программы. Если вы пометите исполняемый файл как 'x86', он не будет работать вообще без WOW64, но если вы используете Any CPU + Prefer 32-bit, он будет работать как 64-битный процесс.
Значения по умолчанию для Visual Studio 2013 - "Любой процессор" и "Предпочитать 32-разрядный" для новых проектов Windows Forms и Windows Service. (Проверено на обновлении 3.) Проекты, обновленные с более старых версий Visual Studio, могут иметь разные настройки. Это может объяснить, почему ProjectB работает, а ProjectA - нет, если ProjectB был создан в более старой версии или кто-то изменил этот параметр.
Проверьте настройки сборки в деталях. В дополнение к выбору архитектуры, есть флажок "предпочтение 32 бит". Этот флажок установлен по умолчанию для клиентских приложений Windows, поэтому ваше приложение WinForms работает в 32-разрядной версии и работает. Скорее всего, ваша служба Windows не проверила это и поэтому работает в 64-битной версии.