558 Stimmen

Wie behebe ich den Visual Studio-Kompilierungsfehler "Unverträglichkeit zwischen Prozessorarchitekturen"?

Ich bin neu in der Projekt-Konfiguration in Visual Studio 2010, habe aber etwas Recherche betrieben und kann dieses Problem immer noch nicht ganz lösen. 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 Abweichung zwischen der Prozessorarchitektur des Projekts, das erstellt wird "MSIL" und der Prozessorarchitektur der Referenz "[internes C#-dll]", "x86".

Es fordert mich auf, zum Konfigurations-Manager zu gehen, um meine Architekturen anzupassen. Das C#-DLL ist mit dem 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 denen 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 eingestellt ist, was die einzige andere Option ist, die angeboten 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 -> Projektbaureihenfolge 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 zeigt x64 an, aber die Warnung besagt, dass das Projekt, an dem gearbeitet wird, "MSIL" ist. Visual Studio sagt mir also, dass es einen Unterschied zwischen Äpfeln und Orangen gibt, obwohl 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 es vorher möglich gewesen sein könnte.

Erstens handelt es sich 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 erklären, dass Ihr Projekt mit "Any CPU" kompatibel ist, aber Sie 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 nicht "Any CPU"-kompatibel. Um die Warnung zu beseitigen, sollten Sie Ihr Projekt tatsächlich von "Any CPU" auf "x86" ändern. Dies ist sehr einfach zu erreichen, 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 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 verschwindet die Warnung und es wird auch angegeben, dass Ihre Assembly oder Ihr Projekt nun nicht mehr "Any CPU"-kompatibel, sondern jetzt spezifisch für x86 ist. Dies 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 Anmerkung: Projekte können in der Regel "Any CPU"-kompatibel sein, wenn es sich um reine .NET-Projekte handelt. Dieses Problem tritt nur auf, wenn Sie eine Abhängigkeit (Dll eines Drittanbieters oder Ihr eigenes C++-verwaltetes Projekt) einführen, das auf eine bestimmte Prozessorarchitektur abzielt.

3 Stimmen

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

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 letztendlich auf die falsche Architektur bereitstellen.

9 Stimmen

Es kann wirklich etwas verletzen. 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 sie eine gültige Warnung ist, gibt es einige Fälle, in denen sie aufgrund der Verwendung von Komponenten von Drittanbietern und anderer Gründe 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 tritt dies in Visual Studio 2010 auf 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 die Zielumgebung meiner Bereitstellung 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 ist, 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 im Microsoft .NET Framework 4.5 RC Readme-Datei. Seltsamerweise wurde es aus der RTM Readme-Datei entfernt.

4 Stimmen

Dies funktioniert, aber nicht für eine Variation der Warnung: "Die referenzierte Assembly ... richtet sich an einen anderen Prozessor als die Anwendung". 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 erstellt wurde"... Dies ist FALSCH. Da Ihr Ziel-Deployment immer 64-Bit ist, können Sie Ihre Plattform auf x64 setzen, was einen geeigneteren Fehler verursacht, 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 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-Bitanzahl verwendet werden soll, auf das Betriebssystem, das die EXE nach eigenem Gutdünken JIT übernimmt. 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 Assemblierungs-Ladens finden Sie hier. Die Zusammenfassung lautet in etwa wie folgt:

  • 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 die folgende Situation: Native.dll (x64) wird von NetA.dll (Any CPU) verwendet, das wiederum von NetB.dll (Any CPU) verwendet wird, das wiederum von App1.exe (x64) verwendet wird. Hier gibt es kein echtes Problem, aber beim Kompilieren von NetA.dll erhalte ich die Warnung. OK, da diese Assembly direkt von Native.dll abhängt, könnte ich sie auch als x64 kennzeichnen. Aber dann beschwert sich das Kompilieren von NetB.dll. Ich möchte NetB.dll als "Any CPU" beibehalten, da es eine gemeinsame Assembly ist, die in einer anderen, reinen .NET-Anwendung verwendet wird. Ich komludiere, dass meine einzige Option ist, die Warnung zu unterdrücken/ignorieren. Richtig?

2 Stimmen

Aufgrund der Abhängigkeit von Native.dll ist Ihre gesamte App/Assembly-Abstammung jetzt x64, egal ob Sie die Warnung unterdrücken oder nicht. Obwohl 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 am Anfang des Stapels nicht geladen.

0 Stimmen

Während die Regel von Gustavo ein guter Grundsatz ist, kann sie nicht für das spezifische in dieser Frage gestellte Problem verwendet werden, da das Projekt bereits von einer Abhängigkeit von einem Assembly eines Drittanbieters abhängt, das die Regel nicht befolgt hat (es ist x86, nicht AnyCPU). Daher müssen solange diese Abhängigkeit besteht, alle Projekte in der gesamten Kette 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 hat tatsächlich nicht die Wahl, welche Bitness der Prozess haben wird. Das wird vollständig durch das EXE-Projekt bestimmt, das erste Assembly, das geladen wird, also ist dessen Plattformziel-Einstellung diejenige, die zählt und die Bitness für den Prozess festlegt.

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

Also ist eine gute Auswahl für die DLLs AnyCPU, damit sie auf beide Arten funktionieren. Das macht viel Sinn für C# DLLs, sie funktionieren tatsächlich auf beide Arten. Aber sicherlich nicht Ihre C++/CLI Mixed-Mode-DLL, die unverwalteten Code enthält, der nur gut funktioniert, 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 wird dennoch ordnungsgemäß erstellt.

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

1 Stimmen

Also, um klar zu sein: Ich baue nicht die EXE, sondern 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 es sich hierbei um einen Fall von connect.microsoft.com/VisualStudio/feedback/details/728901/… handelt - 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

Benutzen 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 wesentlichen Informationen.

0 Stimmen

Hatte nicht über das Ladeversagen gepostet, weil ich nicht 100% sicher war, ob es verbunden war, und bei weiterem Debuggen stellt sich heraus, dass es nicht der Fall ist. Ich benutze VS2010. Aktualisierter Fragetext. Entschuldige mich sehr für die Verwirrung

9voto

yogeshwar gutte Punkte 119

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

  1. Projekt entladen

  2. Projekteigenschaften bearbeiten, d.h. .csproj

  3. füge den folgenden Tag hinzu:

            None
  4. Projekt neu laden

5 Stimmen

Dies löst nicht das Problem. Es deaktiviert lediglich die Warnung für das bestimmte Projekt. Aber in einigen Fällen finde ich es 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