Was bedeutet das Visual Studio-Ziel "Beliebige CPU"?

496

Ich habe einige Verwirrung in Bezug auf die Erstellungsoptionen der .NET-Plattform in Visual Studio 2008.

Was ist das Kompilierungsziel "Beliebige CPU" und welche Art von Dateien werden generiert? Ich habe die ausführbare Ausgabedatei dieses Builds "Any CPU" untersucht und festgestellt, dass es sich um die ausführbaren x86-Dateien handelt (wer würde das nicht kommen sehen!). Gibt es also einen Unterschied zwischen dem Targeting der ausführbaren Datei auf x86 und "Any CPU"?

Eine andere Sache, die mir aufgefallen ist, ist, dass verwaltete C ++ - Projekte diese Plattform nicht als Option haben. Warum ist das so? Bedeutet das, dass mein Verdacht, dass "Any CPU" -Programmdateien einfache 32-Bit-Dateien sind, richtig ist?

Galets
quelle
4
Eine weitere Sache zu prüfen , wenn die Plattform Ziel Verwendung entscheiden: wenn das Ziel des Startup - Projekt ist Any CPUund Sie runnning auf einem 64 - Bit - OS, verlieren Sie die Möglichkeit , zu bearbeiten und weiter während des Debuggens. (Sie debuggen effektiv einen 64-Bit-Prozess). Sie können das Startup-Projekt als Ziel festlegenx86 , um dies beim Debuggen zu umgehen. (Die Versammlungen, auf die aus dem Startprojekt verwiesen wird, zielen möglicherweise weiterhin auf das Ziel ab Any CPU.
Cristian Diaconescu
8
@CristiDiaconescu Mit VS2013 Bearbeiten und fortfahren ist jetzt möglich
ms007
Ich denke, hier sollte angemerkt werden, ob es sich bei dem Projekt um eine Anwendung oder eine Klassenbibliothek handelt, da das Festlegen der Zielbitness für letztere die Verfügbarkeit für konsumierende Anwendungen je nach Plattform beeinträchtigen kann. Ich bin darauf x86gestoßen, weil eine Bibliothek von einer AnyCPUAnwendung verwendet wurde, die ich einstellen musste Prefer 32-bit, um einen Ladefehler zu vermeiden.
SteveCinq

Antworten:

386

Eine AnyCPU- Assembly wird beim Laden in einen 64-Bit-Prozess zu 64-Bit-Code und beim Laden in einen 32-Bit-Prozess zu 32-Bit-Code JIT.

Wenn Sie die CPU einschränken, würden Sie sagen: Es wird etwas von der Assembly verwendet (etwas, das wahrscheinlich nicht verwaltet wird), das 32 Bit oder 64 Bit erfordert.

AnthonyWJones
quelle
3
Wie erstelle ich eine Assembly, die in C ++ auf x64 JIT wird?
Galets
50
C ++ - Projekte werden zu nativem Code kompiliert, sodass der JIT-Compiler nicht beteiligt ist. Sie können also nicht das tun, was Sie verlangen.
Plots
7
@cplotts: Da @galets diese Frage vor 3 Monaten gestellt hat, ist es unwahrscheinlich, dass er Ihre Antwort sieht. Verwenden Sie das @ galets-Präfix in Ihrem Kommentar ähnlich wie hier, damit er über Ihre Antwort informiert wird.
AnthonyWJones
4
@AnthonyWJones Im Allgemeinen haben Sie Recht, es sei denn, der Benutzer ist der OP der Frage, wie in diesem Fall, da er über alle Kommentare benachrichtigt wird.
Mark Hurd
12
@MarkHurd In diesem Fall wird das OP nicht benachrichtigt. OPs werden nicht über Kommentare zu Antworten benachrichtigt , es sei denn, sie werden speziell mit der @ -Syntax gepingt. OPs werden nur automatisch über Kommentare benachrichtigt, die zu ihrer ursprünglichen Frage hinzugefügt wurden.
RSW
322

Ich denke, die meisten wichtigen Dinge wurden gesagt, aber ich dachte nur, ich würde eines hinzufügen: Wenn Sie als Beliebige CPU kompilieren und auf einer x64-Plattform laufen, können Sie keine 32-Bit-DLL-Dateien laden. weil Ihre Anwendung nicht in WoW64 gestartet wurde, diese DLL-Dateien jedoch dort ausgeführt werden müssen.

Wenn Sie als x86 kompilieren, führt das x64-System Ihre Anwendung in WoW64 aus und Sie können 32-Bit-DLL-Dateien laden.

Ich denke, Sie sollten "Beliebige CPU" wählen, wenn Ihre Abhängigkeiten in beiden Umgebungen ausgeführt werden können, aber x86 wählen, wenn Sie 32-Bit-Abhängigkeiten haben. Dieser Artikel von Microsoft erklärt dies ein wenig:

/ CLRIMAGETYPE (Typ des CLR-Bildes angeben)

Im Übrigen stimmt diese andere Microsoft-Dokumentation zu, dass x86 normalerweise eine portablere Wahl ist:

Die Auswahl von x86 ist im Allgemeinen die sicherste Konfiguration für ein App-Paket, da es auf nahezu jedem Gerät ausgeführt werden kann. Auf einigen Geräten wird ein App-Paket mit der x86-Konfiguration nicht ausgeführt, z. B. auf der Xbox oder einigen IoT Core-Geräten. Für einen PC ist ein x86-Paket jedoch die sicherste Wahl und bietet die größte Reichweite für die Gerätebereitstellung. Auf einem erheblichen Teil der Windows 10-Geräte wird weiterhin die x86-Version von Windows ausgeführt.

Paul A Jungwirth
quelle
2
Vielleicht können Sie Ihre Antwort bearbeiten, um zu sagen, wie man feststellen kann, ob eine bestimmte DLL nur 32-Bit ist. Soweit ich weiß, dies sollte das herauszufinden. Ich denke, wir hoffen auf DLLs, die auch "Any CPU" sind und nicht nur x86.
Dan W
+1 eine wichtige Unterscheidung. War erforderlich, um eine 32-Bit-Abhängigkeit zu verwenden (die nicht als solche identifiziert wurde). Die kryptischen Laufzeitfehlermeldungen konnten nicht herausgefunden werden. Aus Versehen änderte sich das CPU-Ziel und es funktionierte, suchte aber nach dem "Warum". Wird eines Tages schön sein, wenn alles 64-Bit ist und die Inkompatibilitätsprobleme kurios erscheinen, wie es jetzt 16bit vs 32bit ist.
Gerald Davis
2
@GeraldDavis - ich stimme zu. Die Ironie ist, dass es keinen technologischen Grund gibt, 32-Bit- und 64-Bit-Abhängigkeiten nicht mischen zu können (nur das Fehlen einer Thunking-Schicht in der CLR), und ich war in den frühen Tagen von .NET enttäuscht, als ich Bit- sah. Bei der Bereitstellung war noch etwas zu beachten (da es sich um eine VM / JIT handelt, wäre dies eine Gelegenheit gewesen, einen etwas höheren Mehrwert zu bieten).
Codenheim
1
@mrjoltcola: Noch schlimmer ist die Art und Weise, wie Microsoft aus gutem Grund entschieden hat. Ich kann mir nicht vorstellen, dass Registrierungseinträge in ein 32-Bit- und 64-Bit-Universum aufgeteilt werden sollten, selbst wenn sie Dinge wie Bildschirmfarben, Standardeinstellungen usw. steuern.
Superkatze
Dies ist die Antwort, nach der ich gesucht habe ... Danke!
Murat von Daminion Software
52

Hier ist eine kurze Übersicht , in der die verschiedenen Build-Ziele erläutert werden.

Wenn Sie aus eigener Erfahrung ein Projekt erstellen möchten, das sowohl auf x86- als auch auf x64-Plattformen ausgeführt werden kann und Sie keine spezifischen x64-Optimierungen haben, würde ich den Build so ändern, dass er speziell "x86" lautet.

Der Grund dafür ist manchmal, dass Sie einige DLL-Dateien erhalten, die kollidieren, oder Code, der WoW in der x64-Umgebung zum Absturz bringt . Durch die spezifische Angabe von x86 behandelt das x64-Betriebssystem die Anwendung als reine x86-Anwendung und stellt sicher, dass alles reibungslos funktioniert.

Dillie-O
quelle
37
Das könnte schrecklich sein, wenn Sie für eine Serverumgebung schreiben und möchten, dass Ihre Anwendung mehr als 2 GB Speicher verwenden kann. Sie deaktivieren auch alle x64-JIT-Optimierungen, die eines Tages möglicherweise nicht mehr verfügbar sind.
Austin Harris
Die Anzahl der Laufzeitprobleme, die ich bei AnyCPU-Kompilierungen hatte, ist die Rechtfertigung, die ich brauchte, um die Verwendung als Build-Option zu beenden, es sei denn, jemand hat ausdrücklich Binärdateien angefordert, die auf beiden funktionieren. Ich habe seit über 10 Jahren niemanden mehr x86-Binärdateien über x64 für irgendetwas anfordern lassen.
KayleeFrye_onDeck
2
"Durch die spezifische Angabe von x86 behandelt das x64-Betriebssystem die App als reine x86-App und stellt sicher, dass alles reibungslos funktioniert." - Entschuldigung, ich bin anderer Meinung. x64 OS wird Ihre x86-App weiterhin in einem WOW64
Mandeep Janjua
Dies ist nur ein schlechter Rat an jemanden, der die Auswirkungen nicht vollständig versteht. @AustinHarris gibt ein gutes Beispiel. Stellen Sie sich einen Web-Worker-Prozess vor, der auf nur wenige GB RAM beschränkt ist (ich musste mich kürzlich in der Produktion damit befassen).
Rgoliveira
47

Lesen Sie den Artikel Erläuterung des Visual Studio .NET-Plattformziels .

Die Standardeinstellung "Beliebige CPU" bedeutet, dass die Assembly nativ auf der CPU ausgeführt wird, auf der sie gerade ausgeführt wird. Das heißt, es wird auf einem 64-Bit-Computer als 64-Bit und auf einem 32-Bit-Computer als 32-Bit ausgeführt. Wenn die Assembly von einer 64-Bit-Anwendung aufgerufen wird, wird sie als 64-Bit-Assembly usw. ausgeführt.

Es wurde berichtet, dass der obige Link fehlerhaft ist. Hier ist ein weiterer Artikel mit einer ähnlichen Erklärung: Was AnyCPU ab .NET 4.5 und Visual Studio 11 wirklich bedeutet

DCNYAM
quelle
1
Link unterbrochen - jetzt zu einer geparkten Domain wechseln.
Jon Adams
Ich habe einen Link zu einem zweiten Artikel mit ähnlichen Informationen hinzugefügt. Ich habe den ersten Link hinterlassen, falls diese Domain jemals reaktiviert wird.
DCNYAM
46

Gutschrift für das Buch "CLR via C #" , siehe dies:

Geben Sie hier die Bildbeschreibung ein

Ivan
quelle
3
Dies ist die genaueste Antwort vom 09/06/2018 und VS 15.8.0
Raikol Amaro
39

"Beliebige CPU" bedeutet, dass .NET Framework beim Starten des Programms anhand der Betriebssystem-Bits ermittelt, ob Ihr Programm in 32-Bit- oder 64-Bit-Schritten ausgeführt werden soll.

Es gibt einen Unterschied zwischen x86 und einer beliebigen CPU : Auf einem x64-System wird Ihre für X86 kompilierte ausführbare Datei als ausführbare 32-Bit-Datei ausgeführt.

Wenn Sie den Verdacht haben, rufen Sie einfach die Visual Studio 2008-Befehlszeile auf und führen Sie Folgendes aus.

dumpbin YourProgram.exe /headers

Es wird Ihnen die Bitterkeit Ihres Programms und vieles mehr zeigen.

AngryHacker
quelle
7
Wenn es in "jede CPU" eingebaut ist, wird es in Dumpbin-Headern als 32-Bit angezeigt.
Kirbinator
34

Jede CPU bedeutet, dass sie auf jeder Plattform funktioniert. Dies liegt daran, dass verwalteter Code Java ähnelt. Stellen Sie sich vor, es wird zu einem Bytecode kompiliert, der zur Laufzeit von .NET Framework interpretiert wird.

C ++ verfügt nicht über diese Option, da sie zu plattformspezifischem Maschinencode kompiliert wurde.

Adam Tegen
quelle
12
+1 für die Beantwortung des einen Teils der Frage, den sonst niemand gestellt hat (über C ++ - Projekte ohne AnyCPU als Option).
Plots
C ++ / CLI kann ohne Maschinencode (/ clr: pure) zu IL-Code kompiliert werden. Sizeof (void *) muss jedoch weiterhin eine Konstante zur Kompilierungszeit in C ++ sein. Selbst wenn kein Maschinencode beteiligt ist, können Sie dennoch keine Binärdatei erstellen, die gleichzeitig mit 32-Bit und 64-Bit funktioniert.
Daniel
5

Ich empfehle diesen Beitrag zu lesen .

Bei Verwendung von AnyCPU ist die Semantik wie folgt:

  • Wenn der Prozess auf einem 32-Bit-Windows-System ausgeführt wird, wird er als 32-Bit-Prozess ausgeführt. CIL wird zu x86-Maschinencode kompiliert.
  • Wenn der Prozess auf einem 64-Bit-Windows-System ausgeführt wird, wird er als 32-Bit-Prozess ausgeführt. CIL wird zu x86-Maschinencode kompiliert.
  • Wenn der Prozess auf einem ARM Windows-System ausgeführt wird, wird er als 32-Bit-Prozess ausgeführt. CIL wird zu ARM-Maschinencode kompiliert.
Mamczas
quelle
8
Nur wenn "32-Bit bevorzugen" ausgewählt ist.
Florian Winter
Welches ist die Standardeinstellung seit Visual Studio 11
Moerwald
@ Moerwald Ich glaube das war ein Fehler, der behoben wurde. Wenn Sie den Beitrag lesen, auf den mamczas verweist, schreibt der Autor: "In der aktuellen Visual Studio-Benutzeroberfläche ist" 32-Bit bevorzugen "abgeblendet und deaktiviert, wo es tatsächlich aktiviert ist ...". In meiner Version von VS (15.8.0) ist die Option immer noch ausgegraut und deaktiviert. Sie funktioniert jedoch wie erwartet (Flag 32BITPREF = FALSE im CorFlags-Abschnitt der kompilierten Assembly)
Raikol Amaro
-1

So habe ich es in Visual Studio 2017 gemacht:

  • Im Solution Explorer
  • Klicken Sie mit der rechten Maustaste auf Ihr Projekt
  • Klicken Sie auf "Eigenschaften"
  • Klicken Sie auf "Build"
  • Deaktivieren Sie die Option "32-Bit bevorzugen".
  • Und Sie können "x64" aus dem Plattformziel auswählen.
M. Fawad Surosh
quelle
Diese Antwort ist nicht zum Thema.
Jonas