558 Stimmen

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

Ich bin neu in der Projektkonfiguration in Visual Studio 2010, aber ich habe einiges recherchiert und kann dieses Problem immer noch nicht ganz lösen. Ich habe eine Visual Studio-Lösung mit einem C++-DLL, das das C#-DLL referenziert. Das C#-DLL referenziert 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 in der Prozessorarchitektur des zu erstellenden Projekts "MSIL" und der Prozessorarchitektur des Verweises "[internes C#-DLL]", "x86".

Es sagt mir, dass ich zum Konfigurations-Manager gehen soll, um meine Architekturen auszurichten. Das C#-DLL ist mit der Plattformziel x86 eingestellt. Wenn ich versuche, dies auf etwas anderes zu ändern, wie zum Beispiel 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. Das scheint die richtige Konfiguration zu sein; sicherlich möchte ich nicht, dass das Projekt für mein C++-Projekt auf x64 gesetzt wird, was die einzige andere Option ist.

Was mache ich hier falsch?

0 Stimmen

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

2 Stimmen

Ich habe nicht genug Informationen, um eine fundierte Empfehlung abzugeben, aber klicken Sie mit der rechten Maustaste auf Ihre Lösung -> Projekt Build 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 darin. Die Plattform oben auf meinem Bildschirm sagt x64, aber die Warnung besagt, dass das Projekt, das erstellt wird, "MSIL" ist. Also sagt Visual Studio mir, dass es eine Diskrepanz 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 dies auch vorher schon möglich gewesen sein könnte.

Zunächst einmal handelt es sich tatsächlich 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 "Any CPU" kompatibel ist, aber eine Abhängigkeit von einem Projekt oder einer .dll-Assembly haben, die entweder x86 oder x64 ist. Aufgrund der x86-Abhängigkeit ist Ihr Projekt technisch gesehen also nicht mit "Any CPU" kompatibel. Um die Warnung zu beseitigen, sollten Sie tatsächlich Ihr Projekt von "Any CPU" auf "x86" ändern. Das 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 "Any CPU" stehen.
  3. Wählen Sie die Option "Any CPU" aus dem Dropdown-Menü aus und wählen Sie dann
  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 angezeigt, dass Ihre Assembly oder Ihr Projekt jetzt nicht mehr mit "Any CPU" kompatibel ist, sondern jetzt spezifisch für x86 ist. Dies gilt auch, wenn Sie ein 64-Bit-Projekt erstellen, das von einer x64-Abhängigkeit abhängt; dann würden Sie einfach x64 auswählen.

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

3 Stimmen

Ich habe gerade das RTW von Visual Studio 2012 installiert und eine bereits bestehende Lösung von 2010 geöffnet und angefangen, dieselbe Warnung zu sehen. Es ist also etwas, das immer noch im RTW vorhanden ist.

7 Stimmen

Das gesagt, ich denke, Davids Antwort ist korrekt, diese Warnung informiert Sie, dass Ihre App wirklich nicht "AnyCPU" ist, sodass Sie auf Probleme stoßen, wenn Sie sie schließlich auf die falsche Architektur bereitstellen.

9 Stimmen

Es könnte tatsächlich etwas schaden. Eine Any CPU-Datei 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 die Plattform meiner Projekte AnyCPU ist und ich eine MS-Bibliothek verwende, die für AMD64 erstellt wurde. Übrigens geschieht das in Visual Studio 2010 und scheint durch die Installation von VS2012 und .Net 4.5 eingeführt worden zu sein.

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

Was ist mit der Warnung? Microsoft hat als Reaktion auf einen Connect-Bericht gepostet, dass eine Option darin besteht, diese Warnung zu deaktivieren. Dies sollten Sie nur tun, wenn Sie sich Ihrer Lösungsarchitektur sehr bewusst sind und Ihr Bereitstellungsziel vollständig verstehen und wissen, dass es außerhalb der Entwicklungsumgebung kein wirkliches Problem darstellt.

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 Variation der Warnung: "Die verwiesene Assembly ... zielt auf einen anderen Prozessor als die Anwendung". Wäre es großartig, wenn es eine ähnliche Einstellung für diese Warnung gäbe?

9 Stimmen

"Mein Projekt-Plattform ist AnyCPU und ich verwende eine MS-Bibliothek, die für AMD64 erstellt wurde"... Dies ist FALSCH. Da Ihre Zielbereitstellung immer 64-Bit ist, können Sie Ihre Plattform auf x64 festlegen, was zu einem angemesseneren Fehler führt, wenn Ihre 64-Bit-Annahme 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 bleiben offen (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 Prozess-Bitanzahl auf das Betriebssystem, das die EXE nach Belieben JITen wird. 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 jedem Prozess kompatibel.

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

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

4 Stimmen

Diese Regel macht für mich Sinn. Aber betrachten Sie folgende Situation: Native.dll (x64), die von NetA.dll (Any CPU) verwendet wird, die von NetB.dll (Any CPU) verwendet wird, die von App1.exe (x64) verwendet wird. Es gibt hier kein echtes Problem, aber beim Kompilieren von NetA.dll erhalte ich die Warnung. Okay, da diese Assembly direkt von Native.dll abhängt, könnte ich sie auch als x64 markieren. Aber dann beschwert sich beim Kompilieren von NetB.dll. Ich möchte NetB.dll als "Any CPU" behalten, weil es eine gemeinsame Assembly in einer anderen, reinen Dot-Net-Anwendung ist. Ich komme zu dem Schluss, dass meine einzige Option ist, 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, egal ob Sie die Warnung unterdrücken oder nicht. Auch wenn 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 beliebiger CPU markiert ist, aber wiederum wird Nativex64 oben im Stapel 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 wird, nicht verwendet werden, da das Projekt bereits eine Abhängigkeit von einer Assembly eines Drittanbieters hat, die die Regel nicht befolgt hat (es ist x86, nicht AnyCPU). Daher müssen solange diese Abhängigkeit besteht, alle Projektketten auf x86 abzielen 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, welche Bitness der Prozess haben wird. Das wird ausschließlich vom EXE-Projekt bestimmt, das erste Assembly, das geladen wird. Also zählt und setzt dessen Zielplattform-Einstellung die Bitness 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 auf jede Weise funktionieren. Das ergibt viel Sinn für C# DLLs, sie funktionieren tatsächlich auf jede Weise. Aber sicher 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 Build-System dazu bringen, Warnungen darüber zu generieren. Genau das haben Sie bekommen. Nur Warnungen, es baut trotzdem ordnungsgemäß.

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

1 Stimmen

Also, um das klarzustellen: Ich baue nicht die EXE, sondern ich baue eine DLL, die mit der EXE von jemand anderem ausgeführt werden soll. Das Ändern des Zielplattforms 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 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 wichtigen Informationen.

0 Stimmen

Hatte nicht über den Ladefehler gepostet, weil ich mir nicht 100% sicher war, ob es verbunden war, und nach weiterem Debuggen stellt sich heraus, dass es nicht der Fall ist. Ich benutze VS2010. Aktualisierte Frage. Entschuldigung für die Verwirrung

9voto

yogeshwar gutte Punkte 119

Ich habe die gleiche Warnung bekommen und habe Folgendes gemacht:

  1. Projekt entladen

  2. Projekteigenschaften bearbeiten, d.h. .csproj

  3. füge den folgenden Tag hinzu:

            None
  4. Projekt wieder laden

5 Stimmen

Dies löst das Problem nicht. Es deaktiviert lediglich die Warnung für das spezielle Projekt. In manchen Fällen finde ich das jedoch 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