Was ist der Zweck der Einstellung "32-Bit bevorzugen" in Visual Studio und wie funktioniert sie tatsächlich?

204

Geben Sie hier die Bildbeschreibung ein

Mir ist nicht klar, woher der Compiler automatisch weiß, dass er bei Bedarf für 64-Bit kompilieren muss. Woher weiß es, wann es sicher auf 32-Bit zielen kann?

Ich bin hauptsächlich neugierig, wie der Compiler weiß, auf welche Architektur er beim Kompilieren abzielen soll. Analysiert es den Code und trifft eine Entscheidung basierend auf dem, was es findet?

Aaron
quelle
Ah danke. Hab das vorher nicht gesehen. Ich bin immer noch gespannt, wie der Compiler automatisch weiß, auf welche Architektur er abzielen soll. Irgendwelche Ideen?
Aaron

Antworten:

219

Microsoft hat einen Blogeintrag Was AnyCPU ab .NET 4.5 und Visual Studio 11 wirklich bedeutet :

In .NET 4.5 und Visual Studio 11 wurde der Käse verschoben. Die Standardeinstellung für die meisten .NET-Projekte ist wieder AnyCPU, aber AnyCPU hat jetzt mehr als eine Bedeutung. Es gibt einen zusätzlichen Untertyp von AnyCPU, "Beliebige CPU 32-Bit bevorzugt", der die neue Standardeinstellung ist (insgesamt gibt es jetzt fünf Optionen für den C # -Compiler-Switch / platform: x86, Itanium, x64, anycpu und anycpu32bitpreferred ). Bei Verwendung der "Prefer 32-Bit" -Variante von AnyCPU lautet die Semantik wie folgt:

  • Wenn der Prozess auf einem 32-Bit-Windows-System ausgeführt wird, wird er als 32-Bit-Prozess ausgeführt. IL 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. IL wird zu x86-Maschinencode kompiliert.
  • Wenn der Prozess auf einem ARM Windows-System ausgeführt wird, wird er als 32-Bit-Prozess ausgeführt. IL wird zu ARM-Maschinencode kompiliert.

Der Unterschied zwischen "Beliebige CPU 32-Bit bevorzugt" und "x86" besteht also nur darin, dass eine auf x86 kompilierte .NET-Anwendung nicht auf einem ARM Windows-System ausgeführt werden kann, sondern eine "Beliebige CPU 32-Bit bevorzugt" -Anwendung wird erfolgreich ausgeführt.

Lex Li
quelle
12
+1. Das Kontrollkästchen "32-Bit bevorzugen" ist nur für ausführbare .NET 4.5+ Projekte aktiviert.
Lee Grissom
12
Ein weiterer Vorteil von anycpu32bitspreferred ist, dass eine andere .exe, die in 64 Bit ausgeführt wird, diese Assembly laden kann.
Bruno Martinez
30
Persönlich finde ich es schrecklich, dass sie dies standardmäßig ohne Tools-Einstellung zum Deaktivieren einstellen. Schlimmer noch, Sie können nicht danach suchen, da es nicht in den csproj-Dateien enthalten ist, es sei denn, es ist deaktiviert! Wahrscheinlich aufgrund der Inkompatibilität von Office Automation mit CPUAny auf einem x64-Computer hinzugefügt, auf dem die meisten Leute 32-Bit-Office installieren.
Dave
6
@BrianDavidBerman gibt es, wenn Sie false auf 32 setzen, aber bevorzugt und x64 oder eine beliebige CPU auf einem 64-Bit-Computer festlegen.
Lex Li
6
Der Unterschied zwischen x86 und jeder bevorzugten 32-Bit-CPU besteht darin, dass im letzteren Fall das Flag largeaddressaware in der ausführbaren Datei gesetzt ist. Dies bedeutet, dass der 32-Bit-Prozess, der unter einem 64-Bit-Betriebssystem ausgeführt wird, 2 GB Speicher im x86-Modus und 4 GB Speicher im 32-Bit-Vorzugsmodus einer beliebigen CPU verwenden kann.
Nic
6

Hier ist eine einfache Antwort:

Anwendungsbogen.

Hinweis: AnyCPU-32bitPreferred ist nur in .NET Version 4.5 und höher verfügbar.

Yousha Aleayoub
quelle
2
Was ist der Unterschied zwischen "läuft als 32-Bit" und läuft als "WoW64". Ich dachte, WoW64 = "Windows (32-Bit) unter Windows64" und wurde benötigt, damit eine 32-Bit-Anwendung ausgeführt werden kann.
Peter Cordes
Gibt es eine Quelle dafür? Scheinbar sagt mir überall noch, dass die Standardeinstellung anycpu32bitpreferred ist, was einen großen Unterschied zu Leuten darstellt, die auf 64-Bit-Windows-Computern laufen (das ist eine Menge).
Ran Sagy
@RanSagy Sie können es einfach testen, indem Sie ein neues Projekt erstellen und überprüfen Project -> Properties -> Build tab -> Platform target... Beachten Sie jedoch, dass dies AnyCPU-32bitPreferrednur in .Net Version 4.5 und höher verfügbar ist. Deshalb ist die Standardeinstellung AnyCPU.
Yousha Aleayoub
In einigen Fällen war meine ausgegraut; Ich hatte nur gehofft, dass es eine Dokumentation darüber gibt, was in .net 4.5+ oder .net Standard / Core (oder wirklich in MSBuild 16) passiert
Ran Sagy
-1

Der Grund ist: Für den Fall, dass Sie mit 64-Bit-Anwendungen nicht mehr Speicher verwenden möchten. Das heißt, wenn Ihre Anwendung AnyCPU ist , möchten Sie als 32-Bit ausgeführt werden.

Um weitere hinzuzufügen, zielt die Einstellung in Visual Studio auf die jeweilige CLR ab:

Visual Studio installiert die 32-Bit-Version der CLR auf einem x86-Computer und sowohl die 32-Bit-Version als auch die entsprechende 64-Bit-Version der CLR auf einem 64-Bit-Windows-Computer. (Da Visual Studio eine 32-Bit-Anwendung ist, wird es bei der Installation auf einem 64-Bit-System unter WOW64 ausgeführt.)

Weitere Informationen finden Sie im Artikel 64-Bit-Anwendungen ( MSDN ).

Peru
quelle
1
Ich bin mir nicht sicher, ob das richtig ist. Nach meinem Verständnis sind ausführbare .NET-Dateien unabhängig von 32 oder 64 immer noch auf 2 GB pro Prozess beschränkt.
JP Richardson
1
Ich habe meine Antwort bearbeitet. Aber nicht sicher, ob dies das ist, wonach Sie suchen :)
Peru
2
@Aaron, der Compiler setzt im Wesentlichen das Flag für die Laufzeit, um zu entscheiden, ob das Laden der Assembly (dh das Blockieren einer Nur-x86-Assembly, die im x64-Prozess geladen werden soll) in Ordnung ist und wie der Prozess (für die neue EXE-Datei) basierend auf Flags gestartet wird. Ich glaube, IL ist für beide Geschmacksrichtungen gleich.
Alexei Levenkov
1
@JPRichardson Ja, du hast recht. In .net 4.5 haben Sie jedoch die Möglichkeit, die Größe zu erhöhen. siehe MSDN
Peru
40
@JPRichardson, weder 32- noch 64-Bit-.Net-ausführbare Datei auf 2 GB pro Prozess beschränkt - Erstens ist der Adressraum pro Prozess eine Einschränkung auf Betriebssystemebene (2/3 + GB für 32-Bit-Prozesse und vieles mehr für 64-Bit), die zweite sogar 32-Bit-Version Verwenden Sie mehr als 2 GB, wenn das Flag "LargeAddressAware" in der ausführbaren Datei gesetzt ist. Die einzigen mir bekannten 2-GB-Einschränkungen betreffen Array- / Zuordnungsgrößen, die durch den Int32-Bereich (ca. 2 GB) begrenzt sind.
Alexei Levenkov