558 Stimmen

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

Ich bin neu in der Projektkonfiguration in Visual Studio 2010, aber ich habe einige Recherchen gemacht 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 ein paar 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 eine Diskrepanz zwischen der Prozessorarchitektur des Projekts, das erstellt wird "MSIL" und der Prozessorarchitektur der Referenz "[interne C# dll]", "x86".

Es sagt mir, dass ich zum Konfigurations-Manager gehen soll, um meine Architekturen abzugleichen. Das C#-DLL ist mit der Plattformziel x86 eingerichtet. Wenn ich versuche, dies auf etwas anderes zu ändern, wie z.B. Any CPU, beschwert es sich, weil eine der externen DLLs, von der es abhängt, das Plattformziel 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 auf x64 festgelegt ist, was die einzige andere Option darstellt.

Was mache ich hier falsch?

0 Stimmen

Was ist die Beschwerde, speziell, wenn Sie es auf "Jede CPU" ändern?

2 Stimmen

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

7 Stimmen

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

612voto

David Sacks Punkte 6306

Diese Warnung scheint mit der neuen Visual Studio 11 Beta und .NET 4.5 eingeführt worden zu sein, obwohl ich vermute, dass dies auch vorher möglich war.

Zunächst einmal handelt es sich nur um eine Warnung. Es sollte nichts ausmachen, wenn Sie es nur mit x86-Abhängigkeiten zu tun haben. Microsoft versucht Sie lediglich zu warnen, wenn Sie angeben, dass Ihr Projekt mit "beliebigem Prozessor" kompatibel ist, aber eine Abhängigkeit von einem Projekt oder .dll-Assembly haben, das entweder x86 oder x64 ist. Da Sie eine x86-Abhängigkeit haben, ist Ihr Projekt technisch gesehen also nicht "beliebig Prozessor" kompatibel. Um die Warnung zu entfernen, sollten Sie tatsächlich Ihr Projekt von "beliebigem Prozessor" 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 sollte "beliebig Prozessor" stehen.
  3. Wählen Sie die Option "beliebig Prozessor" aus dem Dropdown-Menü aus und wählen Sie dann
  4. Wählen Sie in diesem Dialogfeld x86 aus dem Dropdown-Menü "Neue Plattform" und stellen Sie sicher, dass "beliebig Prozessor" 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-Konfigurationen auswählen.

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

Eine andere Anmerkung, Projekte können in der Regel "beliebig Prozessor" kompatibel sein, wenn es sich um reine .NET-Projekte handelt. Dieses Problem tritt nur auf, wenn Sie eine Abhängigkeit (Drittanbieter-DLL oder Ihr eigenes C++-verwaltetes Projekt) einführen, das auf eine spezifische Prozessorarchitektur abzielt.

3 Stimmen

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

7 Stimmen

Das gesagt, denke ich, ist Davids Antwort richtig, diese Warnung informiert dich darüber, dass deine App wirklich nicht "AnyCPU" ist, daher wirst du auf Probleme stoßen, wenn du sie schließlich auf die falsche Architektur bereitstellst.

9 Stimmen

Es kann durchaus etwas beschädigen. Eine beliebige 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 aus anderen Gründen nicht behoben werden kann. Ich habe ein ähnliches Problem, außer dass die Warnung auftritt, weil das Platform meines Projekts AnyCPU ist und ich eine MS-Bibliothek verwende, die für AMD64 gebaut wurde. Dies 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 nur 64-Bit sein wird, kann ich dieses Problem sicher ignorieren.

Was ist mit der Warnung? Microsoft hat in Reaktion auf einen Connect-Bericht gepostet, dass eine Option darin besteht, diese Warnung zu deaktivieren. Sie sollten dies nur tun, wenn Sie sich sehr bewusst über die Architektur Ihrer Lösung 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: "Referenzierte Assembly ... zielt auf einen anderen Prozessor als die Anwendung ab". Es wäre großartig, wenn es eine ähnliche Einstellung für diese Warnung gäbe?

9 Stimmen

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

73voto

Gustavo Mori Punkte 8033

Ein guter Faustregel lautet "offene DLLs, geschlossene EXEs", das heißt:

  • EXE zielt auf das Betriebssystem ab, indem es x86 oder x64 spezifiziert.
  • DLLs bleiben offen (d.h. AnyCPU), damit sie in einem 32-Bit- oder 64-Bit-Prozess instanziiert werden können.

Wenn Sie eine EXE als AnyCPU erstellen, verschieben Sie nur die Entscheidung, welche Prozess-Bitness verwendet werden soll, auf das Betriebssystem, das die EXE nach eigenem Ermessen JIT. 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 ungefähr wie folgt:

  • AnyCPU – lädt als x64- oder x86-Assembly, je nach aufrufendem Prozess
  • x86 – lädt als x86-Assembly; wird nicht aus einem x64-Prozess geladen
  • x64 – lädt als x64-Assembly; wird nicht aus 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. Es besteht kein wirkliches 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 markieren. Aber dann beschwert sich das Kompilieren von NetB.dll. Ich möchte NetB.dll als "Any CPU" beibehalten, 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/zu ignorieren. Ja?

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 fröhlich, da NetB als beliebige CPU markiert ist, aber auch hier wird Nativex64 am Anfang des Stapels nicht geladen.

0 Stimmen

Während die Regel von Gustavo ein guter Grundsatz ist, kann sie für das spezifische Problem, das in dieser Frage gestellt wurde, nicht verwendet werden, da das Projekt bereits von einer Abhängigkeit zu einer Assembly eines Drittanbieters abhängt, die sich nicht an die Regel gehalten hat (es ist x86, nicht AnyCPU). Daher müssen solange die Abhängigkeit besteht, alle Projekte der Projektreihe x86 als Zielplattform haben und nichts anderes.

24voto

Hans Passant Punkte 894572

Die C# DLL ist mit dem Ziel x86 Plattform eingerichtet

Das ist irgendwie das Problem, eine DLL hat nicht wirklich die Wahl, welche Bitness der Prozess haben wird. Das wird vollständig vom EXE-Projekt bestimmt, das ist die erste Assembly, die geladen wird, also zählt und setzt das Plattformziel für den Prozess.

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

Also eine gute Auswahl für die DLLs ist AnyCPU, damit sie in beiden Richtungen funktionieren. Das macht viel Sinn für C# DLLs, sie funktionieren tatsächlich in beiden Richtungen. Aber sicher nicht 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 Build-System dazu bringen, Warnungen darüber zu generieren. Genau das haben Sie bekommen. Nur Warnungen, es baut dennoch ordnungsgemäß.

Probleme einfach ignorieren. 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 sagen: Ich baue nicht die EXE, ich baue eine DLL, die mit der EXE von jemand anderem ausgeführt werden soll. Das Ändern des Plattformziels der C# DLLs auf Any CPU beseitigt die Warnung nicht. Ich frage mich, ob dies ein Fall von connect.microsoft.com/VisualStudio/feedback/details/728901/… ist - Ich würde die Warnung selbst ignorieren, aber tatsächlich kann die EXE die C# DLL laden, aber nicht die C++ DLL, also glaube 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 wichtigen Informationen.

0 Stimmen

Ich hatte nicht über das Ladeproblem gepostet, weil ich nicht zu 100% sicher war, ob es damit zusammenhängt, und nach weiterem Debuggen stellte sich heraus, dass es nicht der Fall ist. Ich benutze VS2010. Frage wurde aktualisiert. Entschuldigung für das Missverständnis.

9voto

yogeshwar gutte Punkte 119

Ich habe die gleiche Warnung erhalten und habe folgendes gemacht:

  1. Projekt entladen

  2. Projekteigenschaften bearbeiten, d.h. .csproj

  3. füge den folgenden Tag hinzu:

            None
  4. Projekt neu laden

5 Stimmen

Das löst das Problem nicht. Es deaktiviert lediglich die Warnung für das spezielle Projekt. Aber in einigen Fällen halte ich dies 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