558 Stimmen

Wie behebe ich den Visual Studio-Kompilierungsfehler "Unstimmigkeit zwischen Prozessorarchitekturen"?

Ich bin neu in der Projekt-Konfiguration in Visual Studio 2010, aber ich habe einige Recherchen durchgeführt und kann dieses Problem immer noch nicht ganz verstehen. Ich habe eine Visual Studio-Lösung mit einem C++-DLL, das auf das C#-DLL verweist. Das C#-DLL verweist auf einige andere DLLs, einige innerhalb meines Projekts und einige externe. Wenn ich versuche, das C++-DLL zu kompilieren, erhalte ich diese Warnung:

Warnung MSB3270: Es gab einen Unterschied zwischen der Prozessorarchitektur des Projekts, das erstellt wird ("MSIL") und der Prozessorarchitektur der Referenz "[internes C#-DLL]", "x86".

Es sagt mir, dass ich zum Konfigurations-Manager gehen soll, um meine Architekturen abzugleichen. Das C#-DLL ist mit der Zielplattform x86 eingerichtet. Wenn ich versuche, dies auf etwas anderes zu ändern, wie zum Beispiel Any CPU, beschwert es sich, weil eine der externen DLLs, von denen es abhängt, die Zielplattform x86 hat.

Wenn ich mir den Konfigurations-Manager anschaue, zeigt er die Plattform für mein C#-DLL als x86 und für mein C++-Projekt als Win32 an. Dies scheint die richtige Konfiguration zu sein; sicherlich möchte ich nicht, dass das Projekt für mein C++-Projekt die Plattform auf x64 festgelegt hat, was die einzige andere Option ist, die präsentiert wird.

Was mache ich hier falsch?

0 Stimmen

Was ist die Beschwerde, insbesondere, wenn Sie es auf Any CPU ändern?

2 Stimmen

Ich habe nicht genug Informationen, um einen fundierten Vorschlag zu machen, aber klicken Sie mit der rechten Maustaste auf Ihre Lösung -> Projekt-Bauauftrag und stellen Sie sicher, dass Ihr C#-Projekt vor dem C++-Projekt erstellt wird. Wenn nicht, gehen Sie zum Tab Abhängigkeiten und teilen Sie VS mit, dass das C++-Projekt vom C#-Projekt abhängt.

7 Stimmen

Visual Studio ist wieder Mist dabei. Die Plattform oben auf meinem Bildschirm zeigt x64 an, aber die Warnung besagt, dass das zu erstellende Projekt "MSIL" ist. Also sagt Visual Studio mir, dass es einen Unterschied zwischen Äpfeln und Orangen gibt, wenn ich keine Äpfel benutze. Können wir es in Visual Stupido umbenennen?

612voto

David Sacks Punkte 6306

Diese Warnung scheint mit dem neuen Visual Studio 11 Beta und .NET 4.5 eingeführt worden zu sein, obwohl ich vermute, dass es auch vorher möglich gewesen sein könnte.

Zunächst einmal handelt es sich hierbei tatsächlich nur um eine Warnung. Es sollte nichts ausmachen, wenn Sie nur mit x86-Abhängigkeiten umgehen. Microsoft versucht Sie lediglich zu warnen, wenn Sie angeben, dass Ihr Projekt mit "Any CPU" kompatibel ist, aber eine Abhängigkeit von einem Projekt oder einer .dll-Assembly haben, die entweder x86 oder x64 ist. Aufgrund Ihrer x86-Abhängigkeit ist Ihr Projekt technisch gesehen daher nicht mit "Any CPU" kompatibel. Um die Warnung zu beseitigen, sollten Sie tatsächlich Ihr Projekt von "Any CPU" auf "x86" ändern. Dies ist sehr einfach zu tun, hier sind die Schritte.

  1. Gehen Sie zum Menüpunkt Build|Konfigurations-Manager.
  2. Finden Sie Ihr Projekt in der Liste, unter Plattform wird "Any CPU" stehen.
  3. Wählen Sie die Option "Any CPU" aus dem Dropdown-Menü aus und dann wählen Sie
  4. Wählen Sie in diesem Dialogfeld x86 aus dem Dropdown-Menü "Neue Plattform" aus und stellen Sie sicher, dass "Any CPU" im Dropdown-Menü "Einstellungen kopieren von" ausgewählt ist.
  5. Klicken Sie auf OK
  6. Sie sollten x86 für sowohl die Debug- als auch die Release-Konfiguration auswählen.

Dadurch wird die Warnung beseitigt und es wird auch festgestellt, dass Ihre Assembly oder Ihr Projekt jetzt nicht mehr mit "Any CPU" kompatibel ist, sondern jetzt spezifisch für x86 ist. Das gilt auch, wenn Sie ein 64-Bit-Projekt erstellen, das eine x64-Abhängigkeit hat; dann würden Sie einfach x64 auswählen.

Noch eine weitere Anmerkung: Projekte können in der Regel "Any CPU"-kompatibel sein, wenn es reine .NET-Projekte sind. Dieses Problem tritt nur auf, wenn Sie eine Abhängigkeit (3rd-Party-dll oder Ihr eigenes C++-verwaltetes Projekt) einführen, die auf eine bestimmte Prozessorarchitektur abzielt.

3 Stimmen

Ich habe gerade die RTW von Visual Studio 2012 installiert und eine bereits vorhandene Lösung von 2010 geöffnet und angefangen, dieselbe Warnung zu sehen, also ist es etwas, das immer noch in der RTW existiert.

7 Stimmen

Das gesagt, ich denke, Davids Antwort ist korrekt, diese Warnung informiert Sie darüber, dass Ihre App tatsächlich nicht "AnyCPU" ist, sodass Sie Probleme haben werden, wenn Sie sie schließlich auf die falsche Architektur bereitstellen.

9 Stimmen

Es kann durchaus etwas schaden. Eine Any CPU-Exe wird auf einem 64-Bit-Betriebssystem als x64 geladen und kann x86-DLLs nicht laden. Wenn Sie also von einer bestimmten Plattform abhängig sind, sollten Sie Ihre Plattform wirklich korrekt einstellen.

164voto

Gio Punkte 1994

Dies ist eine sehr hartnäckige Warnung und obwohl es eine gültige Warnung ist, gibt es einige Fälle, in denen sie aufgrund der Verwendung von Komponenten von Drittanbietern und anderen Gründen nicht gelöst werden kann. Ich habe ein ähnliches Problem, außer dass die Warnung auftritt, weil meine Projektplattform AnyCPU ist und ich eine MS-Bibliothek verwende, die für AMD64 erstellt wurde. Das ist übrigens in Visual Studio 2010 und scheint durch die Installation von VS2012 und .Net 4.5 eingeführt worden zu sein.

Da ich die von mir referenzierte MS-Bibliothek nicht ändern kann und da ich weiß, dass meine Zielbereitstellungsumgebung immer nur 64-Bit sein wird, kann ich dieses Problem sicher ignorieren.

Was ist mit der Warnung? Microsoft hat als Antwort auf einen Connect-Bericht gepostet, dass eine Option darin besteht, diese Warnung zu deaktivieren. Sie sollten dies nur tun, wenn Sie sich sehr über die Architektur Ihrer Lösung im Klaren sind und Ihr Bereitstellungsziel vollständig verstehen und wissen, dass es außerhalb der Entwicklungsumgebung kein wirkliches Problem ist.

Sie können Ihre Projektdatei bearbeiten und diese Eigenschaftsgruppe und Einstellung hinzufügen, um die Warnung zu deaktivieren:

  None

1 Stimmen

Die einzige andere offizielle MS-Referenz zu dieser Lösung, die ich gesehen habe, befindet sich in der Microsoft .NET Framework 4.5 RC Readme-Datei. Seltsamerweise wurde sie aus der RTM-Readme-Datei entfernt.

4 Stimmen

Dies funktioniert, aber nicht für eine Variante der Warnung: "Verwiesene Assembly ... zielt auf einen anderen Prozessor als die Anwendung". Wäre es toll, wenn es eine ähnliche Einstellung für diese Warnung gäbe?

9 Stimmen

"Meine Projekteplattform ist AnyCPU und ich beziehe mich auf eine MS-Bibliothek, die für AMD64 erstellt wurde"... Dies ist FALSCH. Da Ihr Zieldepot immer 64-Bit ist, können Sie Ihre Plattform auf x64 festlegen, was zu einem angemesseneren Fehler führt, wenn Ihre Annahme von 64-Bit jemals verletzt wird, und auch die Warnung verhindert.

73voto

Gustavo Mori Punkte 8033

Eine gute Faustregel lautet "offene DLLs, geschlossene EXEs", das heißt:

  • EXE zielt auf das Betriebssystem ab, indem x86 oder x64 spezifiziert wird.
  • DLLs werden offen gelassen (d.h. AnyCPU), damit sie innerhalb eines 32-Bit- oder 64-Bit-Prozesses instanziiert werden können.

Wenn Sie eine EXE als AnyCPU erstellen, verschieben Sie lediglich die Entscheidung über die Prozessbitzahl an das Betriebssystem, das die EXE nach eigenem Ermessen JIT-kompiliert. Das heißt, ein x64-Betriebssystem wird einen 64-Bit-Prozess erstellen, ein x86-Betriebssystem wird einen 32-Bit-Prozess erstellen.

Das Erstellen von DLLs als AnyCPU macht sie mit beiden Prozessen kompatibel.

Weitere Informationen zu den Feinheiten des Assembly-Ladens finden Sie hier. Die Zusammenfassung lautet in etwa:

  • AnyCPU – wird als x64- oder x86-Assembly geladen, abhängig vom aufrufenden Prozess
  • x86 – wird als x86-Assembly geladen; wird nicht von einem x64-Prozess geladen
  • x64 – wird als x64-Assembly geladen; wird nicht von einem x86-Prozess geladen

4 Stimmen

Diese Regel macht für mich Sinn. Aber betrachten Sie die folgende Situation: Native.dll (x64) wird von NetA.dll (Any CPU) verwendet, das von NetB.dll (Any CPU) verwendet wird, das von App1.exe (x64) verwendet wird. Hier gibt es kein echtes Problem, aber beim Kompilieren von NetA.dll erhalte ich die Warnung. OK, da dieses Assembly direkt von Native.dll abhängt, könnte ich es auch als x64 kennzeichnen. Aber dann beschwert sich das Kompilieren von NetB.dll. Ich möchte NetB.dll als "Any CPU" behalten, da es sich um ein gemeinsames Assembly handelt, das in einer anderen reinen .NET-Anwendung verwendet wird. Ich komme zu dem Schluss, dass meine einzige Option darin besteht, die Warnung zu unterdrücken/ignorieren. Richtig?

2 Stimmen

Aufgrund der Abhängigkeit von Native.dll ist Ihre gesamte App/Assembly-Linie jetzt x64, unabhängig davon, ob Sie die Warnung unterdrücken oder nicht. Während die Unterdrückung in Ihrem Szenario funktioniert, könnten in Zukunft seltsame Situationen auftreten. Zum Beispiel 1) wird die Assembly NetB in einer x86-Umgebung verwendet, in der Nativex64 nicht geladen wird, oder 2) Ihr Kunde möchte eine x86-Version von App1.exe, und Sie kompilieren glücklich, da NetB als einige CPU markiert ist, aber erneut wird Nativex64 am oberen Rand des Stapels nicht laden.

0 Stimmen

Während die Regel von Gustavo ein guter Grundsatz ist, kann sie für das spezifische Problem, das in dieser Frage gestellt wird, nicht verwendet werden, da das Projekt bereits von einer Drittanbieter-Assembly abhängt, die die Regel nicht befolgt hat (sie ist x86, nicht AnyCPU). Daher müssen solange die Abhängigkeit besteht, die gesamte Projektkette x86 als Ziel haben und nichts anderes.

24voto

Hans Passant Punkte 894572

Die C# DLL ist mit dem Zielplattform x86 eingerichtet

Das ist irgendwie das Problem, eine DLL kann tatsächlich nicht wählen, welches die Bittigkeit des Prozesses sein wird. Das wird vollständig vom EXE-Projekt bestimmt, das ist die erste Assembly, die geladen wird, also ist dessen Plattformziel-Einstellung diejenige, die zählt und die Bittigkeit für den Prozess festlegt.

Die DLLs haben keine Wahl, sie müssen mit der Bittigkeit des Prozesses kompatibel sein. Wenn sie es nicht sind, bekommen Sie ein großes Kaboom mit einer BadImageFormatException, wenn Ihr Code versucht, sie zu verwenden.

Also ist eine gute Auswahl für die DLLs AnyCPU, damit sie in beiden Fällen funktionieren. Das ergibt viel Sinn für C# DLLs, sie funktionieren tatsächlich in beiden Fällen. Aber sicherlich nicht für Ihre C++/CLI-Mixed-Mode-DLL, sie enthält nicht verwalteten Code, der nur gut funktionieren kann, wenn der Prozess im 32-Bit-Modus läuft. Sie können das Bausystem dazu bringen, Warnungen darüber zu generieren. Das ist genau das, was Sie bekommen haben. Nur Warnungen, es erstellt immer noch ordnungsgemäß.

Einfach das Problem loswerden. Setzen Sie das Plattformziel des EXE-Projekts auf x86, es wird mit keiner anderen Einstellung funktionieren. Und behalten Sie einfach alle DLL-Projekte bei AnyCPU.

1 Stimmen

Also, um es klar zu stellen: Ich baue nicht die EXE, ich baue eine DLL, die mit der EXE eines anderen Benutzers ausgeführt werden soll. Das Ändern des Zielplattform der C#-DLLs auf Any CPU beseitigt die Warnung nicht. Ich frage mich, ob es sich dabei um einen Fall von connect.microsoft.com/VisualStudio/feedback/details/728901/… handelt - Ich würde die Warnung selbst ignorieren, aber tatsächlich ist die EXE in der Lage, die C#-DLL zu laden, aber nicht die C++-DLL, daher denke ich, dass dies ein echtes Problem ist.

0 Stimmen

Verwenden Sie tatsächlich VS2010? Es war auch überhaupt nicht klar, dass Sie die C++/CLI DLL nicht laden konnten. Was ist die Diagnose? Aktualisieren Sie Ihre Fragen mit diesen essentiellen Informationen.

0 Stimmen

Hatte nicht über das Ladeproblem gepostet, weil ich nicht zu 100% sicher war, ob es damit zusammenhängt, und nach weiterem Debugging stellt sich heraus, dass es nicht der Fall ist. Ich benutze VS2010. Frage aktualisiert. Entschuldigung für die Verwirrung.

9voto

yogeshwar gutte Punkte 119

Ich habe die gleiche Warnung erhalten, als ich dies gemacht habe:

  1. Projekt entladen

  2. Projekteigenschaften bearbeiten, d.h. .csproj

  3. fügen Sie das folgende Tag hinzu:

            None
  4. Projekt neu laden

5 Stimmen

Das löst das Problem nicht. Es deaktiviert lediglich die Warnung für das bestimmte Projekt. Aber in manchen Fällen halte ich es für eine gültige Lösung. Danke!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X