Як виправити помилку компіляції Visual Studio, «невідповідність між архітектурою процесора»?


458

Я новачок у конфігурації проектів у Visual Studio 2010, але я провів деякі дослідження і досі не можу вирішити цю проблему. У мене є рішення Visual Studio з DLL C ++ з посиланням на C # DLL. CL DLL посилається на кілька інших DLL-файлів, деякі в рамках мого проекту та деякі зовнішні. Коли я намагаюся скласти DLL C ++, я отримую це попередження:

попередження MSB3270: Існувала невідповідність між архітектурою процесора проекту "MSIL" та архітектурою процесора посилань "[внутрішній C # dll]", "x86".

Це підказує мені перейти до Менеджера конфігурацій, щоб вирівняти свої архітектури. DLL C # налаштовано з цільовою платформою x86. Якщо я спробую змінити це на щось інше, як-от будь-який процесор, він скаржиться, оскільки одна із зовнішніх DLL-файлів, від яких залежить, має цільову платформу x86.

Коли я дивлюся на Configuration Manager, він показує платформу для мого C # DLL як x86, а для мого проекту C ++ як Win32. Це здається правильним налаштуванням; звичайно, я не хочу, щоб проект мого проекту C ++ мав платформу, встановлену на x64, що є єдиним іншим варіантом.

Що я тут роблю неправильно?


Яка скарга, зокрема, коли ви змінюєте її на будь-який процесор?
lordcheeto

2
У мене не вистачає інформації, щоб зробити поінформовану пропозицію, але клацніть правою кнопкою миші ваше рішення -> Замовлення на створення проекту та переконайтеся, що ваш проект C # будується перед проектом C ++. Якщо це не так, перейдіть на вкладку Залежності та повідомте VS, що проект C ++ залежить від проекту C #.
lordcheeto

2
Visual Studio знову лайно в цьому. Платформа вгорі мого екрана пише x64, але попередження говорить, що проект, що будується, - "MSIL". Тож Visual studio каже мені, що між яблуками та апельсинами є невідповідність, коли я не використовую яблука. Чи можемо ми перейменувати його на Visual Stupido?
Пол Маккарті

Наскільки мене турбує, це помилка у Visual Studio. Я вибираю x64 як цільову платформу, і це говорить мені, що я будую проект для MSIL.
Пол Маккарті

Коротка відповідь - якщо ваш проект залежить від x86 або x64, ви не можете використовувати будь-який процесор (що стосується лише чистих програм .NET). Таким чином, ви повинні створити для x64 або x32, а не для будь-якого процесора. Це відбувається від Дейва відповіді
Зар

Відповіді:


512

Це попередження, мабуть, було введено з новими Visual Studio 11 Beta та .NET 4.5, хоча, мабуть, це можливо було раніше.

По-перше, це насправді лише попередження. Це нічого не повинно зашкодити, якщо ви просто маєте справу із залежностями x86. Microsoft просто намагається попередити вас, коли ви заявляєте, що ваш проект сумісний з "Будь-яким процесором", але у вас залежність від проекту або .dll-збірки, що є x86 або x64. Оскільки у вас залежність від x86, технічно ваш проект не сумісний з "Будь-яким процесором". Щоб попередження пройшло, вам слід змінити проект з "Будь-який процесор" на "x86". Це зробити дуже просто, ось кроки.

  1. Перейдіть до пункту меню Build | Configuration Manager.
  2. Знайдіть свій проект у списку, під Платформою він напише "Будь-який процесор"
  3. Виберіть у спадному меню опцію "Будь-який процесор", а потім виберіть <New..>
  4. У цьому діалоговому вікні виберіть x86 у спадному меню "Нова платформа" та переконайтесь, що в спадному меню "Копіювати налаштування з" вибрано "Будь-який процесор".
  5. Натисніть ОК
  6. Вам потрібно вибрати x86 для конфігурацій налагодження та випуску.

Це призведе до відмови попередження, а також стверджує, що ваша збірка або проект вже не сумісний з "Будь-яким процесором", а тепер є специфічним для x86. Це також застосовується, якщо ви будуєте 64-бітний проект, який має залежність x64; ви б просто вибрати x64 замість цього.

Ще одна примітка: проекти можуть бути сумісні з "будь-яким процесором", якщо вони є чистими .NET проектами. Ця проблема виникає лише в тому випадку, якщо ви запровадите залежність (сторонній dll або власний проект, керований C ++), яка націлена на конкретну архітектуру процесора.


3
Щойно я встановив RTW Visual Studio 2012 і відкрив попереднє рішення 2010 року і почав бачити те саме попередження, тож це щось ще існує в RTW.
Тод Томсон

4
Зважаючи на це, я вважаю, що відповідь Девіда є правильною, це попередження дає вам знати, що ваш додаток насправді не "AnyCPU", тому ви зіткнетеся з проблемами, коли в кінцевому підсумку буде розгорнуто його в неправильній архітектурі.
Тод Томсон

6
Це дуже добре МОЖЕ щось завдати шкоди. Будь-який exe-процесор завантажиться як x64 на 64-бітній ОС і не зможе завантажити x86 dll. Тож якщо у вас залежність від певної платформи, ви дійсно повинні правильно встановити свою платформу.
Яур

1
Меню збірки, здається, відсутнє в VS C # 2010 Express. Як мені дістатися до нього? Я б хотів, щоб вони не приховували речі.
Xonatron

1
Щойно з'ясували, як увімкнути меню збірки в Visual Studio 2010 Express: меню Інструменти -> Налаштування -> виберіть "Налаштування експертів"
Xonatron

144

Це дуже вперте попередження, і хоча воно є дійсним попередженням, є деякі випадки, коли його неможливо вирішити через використання сторонніх компонентів та інших причин. У мене є аналогічна проблема, за винятком попередження, оскільки платформа моїх проектів - AnyCPU, і я посилаюся на бібліотеку MS, побудовану для AMD64. Це, до речі, у Visual Studio 2010, і, здається, було представлено шляхом встановлення VS2012 та .Net 4.5.

Оскільки я не можу змінити бібліотеку MS, на яку я посилаюсь, і оскільки я знаю, що моє цільове середовище розгортання буде коли-небудь 64-бітним, я можу сміливо ігнорувати цю проблему.

А як щодо попередження? Microsoft опублікував у відповідь на звіт Connect що одним із варіантів є відключення цього попередження. Вам слід це зробити лише тому, що ви дуже обізнані зі своєю архітектурою рішення і повністю розумієте свою ціль розгортання і знаєте, що це насправді не проблема поза середовищем розробки.

Ви можете відредагувати файл проекту та додати цю групу властивостей та налаштування, щоб вимкнути попередження:

<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>

1
Єдине інше офіційне посилання MS на це рішення, яке я бачив, - це файл Microsoft .NET Framework 4.5 RC Readme . Як не дивно, його видалили з RTM-файла Readme.
JohnC

4
Це працює, але не для зміни попередження: "Посилання на посилання ... спрямовується на інший процесор, ніж додаток". Було б чудово, якби було подібне налаштування для цього попередження?
Джиммі

6
"моя платформа проектів - AnyCPU, і я посилаюсь на бібліотеку MS, побудовану для AMD64" ... Це WRONG. Оскільки ваша цільова розгортання завжди 64-розрядна, ви можете встановити свою платформу на x64, що робить більш доцільною помилку, якщо ваше 64-бітове припущення коли-небудь порушиться, а також запобігає попередження.
Бен Войгт

2
@BenVoigt відмінна ідея в теорії, але VS, будучи процесом x86, потребує x86 побудови елементів керування для запуску таких матеріалів, як Windows Forms Designer, навіть якщо ваша програма коли-небудь буде 64-бітною. Це поважна, але невдала причина використовувати помилкову збірку "Будь-який процесор".
jrh

1
@jrh: Потім введіть графічний інтерфейс у проект DLL і побудуйте його як AnyCPU. EXE повинен бути позначений правильною архітектурою, щоб відповідати нативним залежностям. Належне відокремлення графічного інтерфейсу від логіки проходить довгий шлях (хоча він все ще має свої межі, наприклад, коли нативний код стає частиною GUI, але тоді підтримка дизайнера є втраченою причиною, якщо ви не будуєте весь проект для обох x86 та x64)
Ben Voigt

61

Хорошим правилом є "відкриті DLL, закриті EXE", тобто:

  • EXE націлений на ОС, вказавши x86 або x64.
  • DLL залишаються відкритими (тобто AnyCPU), щоб їх можна було екземплярувати в 32-бітному або 64-бітному процесі.

Коли ви будуєте EXE як AnyCPU, все, що ви робите, - це відкласти рішення про те, який біт процесу використовувати для ОС, який буде СРІВИТИ EXE на свій смак. Тобто, x64 ОС створить 64-бітний процес, а x86 ОС створить 32-бітний процес.

Побудова DLL як AnyCPU робить їх сумісними з будь-яким процесом.

Детальніше про тонкощі завантаження монтажу дивіться тут . Підсумкове керівництво містить таке:

  • AnyCPU - завантажується як складання x64 або x86, залежно від процесу виклику
  • x86 - завантажує як складання x86; не завантажуватиметься з процесу x64
  • x64 - завантажує як складання x64; не завантажуватиметься з процесу x86

4
Це правило має для мене сенс. Але врахуйте наступну ситуацію: Native.dll (x64) використовується NetA.dll (будь-який процесор), використовуваний NetB.dll (будь-який процесор), який використовується App1.exe (x64). Тут немає жодної реальної проблеми, але компіляція NetA.dll дає мені попередження. Добре, оскільки ця збірка безпосередньо залежить від Native.dll, я можу також позначити її як x64. Але потім компіляція NetB.dll скаржиться. Я хочу зберегти NetB.dll як "Будь-який процесор", тому що це звичайна збірка, що використовується в іншому додатку з чистою точкою мережі. Я роблю висновок, що єдиний мій варіант - придушити / ігнорувати попередження. Так?
Стів Роббінс

2
Через залежність від Native.dll вся ваша програма програми / збірки зараз x64, будь то подавлення попередження чи ні. Хоча придушення працює у вашому сценарії, в майбутньому можуть виникнути дивні ситуації. Наприклад, 1) збірка NetB використовується в середовищі x86, де Nativex64 не завантажується, або 2) ваш клієнт бажає версії App1.exe x86, і ви збираєтеся щасливо, оскільки NetB позначений як будь-який процесор, але знову ж таки, Nativex64 у верхній частині стека не завантажуватиметься
Густаво Морі

Хоча правило Густаво є хорошим принципом, воно не може бути використане для конкретної проблеми, заданої в цьому питанні, оскільки проект вже має залежність від сторонньої збірки, яка не слідувала правилу (це x86, а не AnyCPU). Отже, поки існує залежність, цілий ланцюжок проектів повинен орієнтуватися на x86 і більше нічого.
Девід Бург

23

DLL C # налаштовано з цільовою платформою x86

Що таке проблема, DLL насправді не може вибрати, якою буде біт процесу. Це повністю визначено проектом EXE, це перша збірка, яка завантажується, тому її цільова настройка Platform - це та, яка рахує та встановлює біт процесу.

У DLL немає вибору, вони повинні бути сумісні з бітом процесу. Якщо їх немає, то ви отримаєте великий Kaboom з BadImageFormatException, коли ваш код намагається їх використовувати.

Тож хороший вибір DLL - це AnyCPU, тому вони працюють в будь-якому випадку. Те , що робить багато сенсу для бібліотек DLL C #, вони роблять роботу так чи інакше. Але впевнено, що ваша DLL зі змішаним режимом C ++ / CLI не містить керованого коду, який може працювати добре лише тоді, коли процес працює в 32-бітному режимі. Ви можете отримати систему складання, щоб генерувати попередження про це. Це саме те, що ви отримали. Просто попередження, він все ще належним чином будується.

Просто виправте проблему. Встановіть ціль платформи EXE на x86, вона не буде працювати з будь-якими іншими параметрами. І просто зберігайте всі проекти DLL в AnyCPU.


1
Отже, щоб було зрозуміло: я не будую EXE, я будую DLL для запуску з чужим EXE. Змінення цілі платформи C # DLL на будь-який процесор не усуває попередження. Мені цікаво, чи це випадок connect.microsoft.com/VisualStudio/feedback/details/728901/… - я б ігнорував саме попередження, але насправді EXE може завантажувати DLL C #, але не CL + DLL тому я думаю, що це справжня проблема.
Пол Істлунд

Ви фактично використовуєте VS2010? Також зовсім не було зрозуміло, що ви не можете завантажити DLL C ++ / CLI. Що таке діагностика? Оновіть свої запитання за допомогою цієї важливої ​​інформації.
Ганс Пасант

Не повідомляв про збій завантаження, тому що я не був на 100% впевнений, що він підключений, а при подальшій налагодженні виявляється, що його немає. Я використовую VS2010. Оновлений текст запитання. Дуже шкода плутанини
Пол Істлунд

1
Ви не задокументували жодної помилки чи винятку, пов’язаної із завантаженням DLL. Я не можу вам допомогти, якщо ви не скажете мені те, що знаєте. Удачі з цим.
Ганс Пасант

5

Я отримував таке ж попередження, як це робив:

  1. розвантажити проект
  2. редагувати властивості проекту, тобто .csproj
  3. додати наступний тег:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
  4. Перезавантажте проект


2
Це не вирішує питання. Це просто відключення попередження для конкретного проекту. Але в деяких випадках я вважаю це правильним рішенням. Дякую!
Крихітні

4

У мене сьогодні була ця проблема, і просто розгляд конфігурацій будівлі у Visual Studio не допомогло, тому що вона показала будь-який процесор як для проекту, який не будував, так і посилався на нього.

Потім я заглянув у csproj згаданого проекту і виявив таке:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>

Якось цей PlatformTarget був доданий посеред зміни конфігурації, і IDE, схоже, не бачив цього.

Видалення цього рядка з посиланого проекту вирішило мою проблему.


На це мені знадобився цілий день. Дуже дякую! :)
SohamC

3

Якщо ваша C # DLL має залежність на основі x86, то сама DLL повинна бути x86. Я насправді не бачу цього шляху. VS скаржиться на зміну його на (наприклад) x64, оскільки 64-бітний виконуваний файл не може завантажити 32-бітні бібліотеки.

Я трохи розгублений щодо конфігурації проекту C ++. Попереджувальне повідомлення, яке було надано для складання, говорить про те, що воно було націлене на AnyCPU, оскільки воно повідомляло про [MSIL] платформу, на яку націлено, але ви вказали, що конфігурація проекту насправді була Win32. Народний додаток Win32 не повинен включати MSIL - хоча, ймовірно, потрібно мати підтримку CLR, якщо він взаємодіє з бібліотекою C #. Тому я думаю, що в інформаційній стороні є кілька прогалин.

Чи можу я з повагою попросити вас переглянути та опублікувати трохи детальніше точну конфігурацію проектів та як вони взаємопов'язані? Раді допомогти надалі, якщо можливо.


3

На додаток до відповіді Девіда Сакса, вам може знадобитися перейти на Buildвкладку Project Propertiesі встановити Platform Targetзначенняx86 для проекту , який дає вам ці попередження. Хоча ви, можливо, очікуєте, що він є, цей параметр, здається, не ідеально синхронізований з налаштуваннями в менеджері конфігурацій.


2

Для проектів C # ціль x86 робить те, що звучить. У ньому сказано, що ця збірка підтримує лише архітектури x86. Так само і для x64. Будь-який процесор з іншого боку говорить, що мені байдуже, яка архітектура, я підтримую і те, і інше. Отже, наступні 2 запитання (1) яка конфігурація виконуваного файлу, який використовує ці файли? та (2) що таке бітвашої ОС / комп’ютера? Причина, яку я запитую, полягає в тому, що якщо ваш виконуваний файл компілюється для роботи в 64-бітовому режимі, він ПОТРІБНУЄ всі залежності, щоб мати можливість працювати і в 64-бітному режимі. Ваша збірка будь-якого процесора повинна бути завантажена, але, можливо, вона посилається на якусь іншу залежність, яка може працювати лише в конфігурації x86. Перевірте всі залежності та залежності від залежностей, щоб переконатися, що все є "Будь-який процесор" або "x64", якщо ви плануєте запускати виконуваний файл у 64-бітному режимі. Інакше у вас виникнуть проблеми.

Багато в чому Visual Studio не спрощує складання суміші будь-якого процесора та різних складових архітектури. Це можливо, але це часто вимагає, щоб збірка, яка в іншому випадку була б "Будь-який процесор", повинна бути складена окремо для x86 та x64, оскільки деяка залежність залежностей десь має дві версії.


Чи доречна конфігурація виконуваного файлу, оскільки я отримую невдачу лише в спробі побудови DLL? (Хоча це x86.) Мій комп'ютер x64.
Пол Істлунд

2
Саме виконуваний файл визначає, який біт буде використовуватися. Якщо виконуваний файл працює як x64, то все, що він завантажується (прямо чи опосередковано), має бути x64 або будь-який процесор. Якщо виконуваний файл працює як x86, то все, що завантажується (прямо чи опосередковано), має бути x86 або Any CPU.
Джонатан Декарло

1

У мене були подібні проблеми і раніше, зокрема при додаванні тестового рішення до вже існуючого рішення x64, наприклад SharePoint. У моєму випадку, схоже, це пов'язано з тим, що певні шаблони проектів додаються як певні платформи за замовчуванням.

Ось рішення, яке часто працює для мене: встановіть усе на правильну платформу в Менеджері конфігурацій (активне налаштування конфігурації, як правило, налагодження, є хорошим способом дістатися до неї) та платформу проекту (у властивостях проекту), потім побудувати, а потім повернути все до AnyCPU. Іноді мені доводиться видаляти та повторно додавати деякі залежності (DLL-файли у властивостях кожного проекту), а іноді "Запустити тести в 32-бітному або 64-бітному процесі" (двічі клацніть на Local.testsettings та перейдіть до Hosts).

Мені здається, що це просто налаштування чогось, а потім його повернення, але, мабуть, більше відбувається за лаштунками, яких я не бачу. Однак для мене це працювало досить послідовно в минулому.


1

Для мого проекту у мене є вимога мати можливість складати і до x86, і до x64. Проблема в тому, що коли ви додаєте посилання під час використання однієї, то вона скаржиться, коли ви будуєте іншу.

Моє рішення полягає в тому, щоб вручну редагувати * .csproj файли так, щоб такі рядки:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=x86"/>

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64"/>

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"/>

змінити це:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral"/>

1

У мене була подібна проблема, це було викликано тестом DLL MS UNIT. Мій додаток WPF був складений як x86, але блок DLL (з посиланням на EXE-файл) як "Будь-який процесор". Я змінив тестовий DLL модуля для компіляції для x86 (такий же, як EXE), і він був повторно використаний.



0

Повинен бути спосіб зробити .NET EXE / DLL AnyCPU, і будь-які некеровані DLL, залежні від компільованого як з x86, так і з x64, обидва в комплекті, можливо, з різними іменами, а потім модуль .NET динамічно завантажує правильний на основі його часу виконання. архітектура процесора. Це зробило б AnyCPU потужним. Якщо DLL C ++ підтримує лише x86 або x64, то AnyCPU, звичайно, безглуздо. Але поєднання обох ідей, які я ще бачив, реалізованих як менеджер конфігурації, навіть не надає засобів для побудови одного і того ж проекту вдвічі з іншою конфігурацією / платформою для багаторазового поєднання, що дозволяє AnyCPU або навіть інші концепції, такі як будь-яка конфігурація.


2
Ласкаво просимо в stackoverflow! чи можете ви спробувати трохи сфокусувати / переформатувати цю відповідь?
Корлі Бригман

Це здається, що це спричинило б гарне запитання, або повідомлення в блозі чи запит на функцію підключення ... насправді це не відповідає.
Бен Войгт

0

У мене було дуже подібне попередження в моєму складі. Мої проекти були встановлені на .NET 4.5, на сервері збирання встановлено Windows 8.1 SDK (для .NET 4.5.1). Після оновлення моїх проектів, спрямованих на .NET 4.5.1 (для мене це не було проблемою, було абсолютно новим додатком), я більше не отримував попередження ...


0

Я вирішив це попередження, змінивши "Менеджер конфігурацій" на "Випуск" (Змішана платаформа).


0

Я отримав це попередження в Visual Studio 2012, коли компілював завдання сценарію конвеєра SSIS для SQL Server 2012 SP1 - до моменту встановлення SQL Server 2012 SP2.


0

У мене була така ж проблема із підключенням до відкриття SQLite, і за допомогою Nuget та встановлення компонента, що використовується у проекті (SQLite), це виправлено! спробуйте встановити свій компонент таким чином і перевірте результат


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.