Co oznacza cel „Any CPU” programu Visual Studio?

494

Mam pewne wątpliwości dotyczące opcji kompilacji platformy .NET w programie Visual Studio 2008.

Co to jest cel kompilacji „Any CPU” i jakie pliki generuje? Sprawdziłem wyjściowy plik wykonywalny tej kompilacji „Any CPU” i stwierdziłem, że są to pliki wykonywalne x86 (które nie widziałyby tego nadchodzącego!). Czy jest jakaś różnica między kierowaniem pliku wykonywalnego na x86 a „dowolnym procesorem”?

Inną rzeczą, którą zauważyłem, jest to, że zarządzane projekty C ++ nie mają tej platformy jako opcji. Dlaczego? Czy to oznacza, że ​​moje podejrzenie, że pliki wykonywalne „Any CPU” są zwykłymi plikami 32-bitowymi, jest słuszne?

galety
źródło
4
Jeszcze jedna rzecz do rozważenia przy podejmowaniu decyzji, której docelowej platformy użyć: jeśli celem projektu startowego jest Any CPUi działasz w 64-bitowym systemie operacyjnym, tracisz możliwość edycji i kontynuowania podczas debugowania. (Skutecznie debugujesz proces 64-bitowy). Można ustawić cel projektu Autostart,x86 aby omijał to podczas debugowania. (Zespoły przywołane w projekcie startowym mogą nadal być celem Any CPU.
Cristian Diaconescu,
8
@CristiDiaconescu Z VS2013 Edycja i kontynuacja jest teraz możliwa
ms007
Myślę, że powinna tu być uwaga na temat tego, czy projekt jest aplikacją, czy biblioteką klas, ponieważ ustawienie docelowej bitowości dla tej ostatniej może mieć wpływ na jej dostępność do aplikacji konsumujących w zależności od platformy. Natknąłem się na to, x86że AnyCPUaplikacja została zużyta przez bibliotekę, w której musiałem ustawić, Prefer 32-bitaby uniknąć błędu ładowania.
SteveCinq

Odpowiedzi:

384

AnyCPU będzie JIT do kodu 64-bitowego, gdy zostanie załadowany do procesu 64-bitowego i 32-bitowego, gdy zostanie załadowany do procesu 32-bitowego.

Ograniczając procesor, można by powiedzieć: Zespół używa czegoś (prawdopodobnie niezarządzanego), który wymaga 32 bitów lub 64 bitów.

AnthonyWJones
źródło
3
więc, jak utworzyć asembler, który będzie JIT do x64 w C ++?
galets
50
Projekty C ++ kompilują się do kodu natywnego, więc kompilator JIT nie jest zaangażowany ... dlatego nie możesz zrobić tego, o co prosisz.
cplotts
7
@cplotts: odkąd @galets zadał to pytanie 3 miesiące temu, jest mało prawdopodobne, że zobaczy twoją odpowiedź. Skorzystaj z prefiksu @galets w swoim komentarzu, podobnie jak tutaj, aby otrzymać powiadomienie o Twojej odpowiedzi.
AnthonyWJones
4
@AnthonyWJones Ogólnie masz rację, z wyjątkiem sytuacji, gdy użytkownik jest OP pytania, tak jak w tym przypadku, ponieważ otrzyma powiadomienie o wszystkich komentarzach.
Mark Hurd
12
@MarkHurd Właściwie w tym przypadku OP nie zostanie powiadomiony. Operatorzy PO nie są powiadamiani o komentarzach do odpowiedzi, chyba że są pingowani przy użyciu składni @. OP tylko automatycznie otrzymują powiadomienia o komentarzach dodanych do ich pierwotnego pytania.
RSW
320

Myślę, że większość ważnych rzeczy została już powiedziana, ale pomyślałem, że dodam jedną rzecz: jeśli skompilujesz jako Any CPU i uruchomisz platformę x64, nie będziesz w stanie załadować 32-bitowych plików DLL, ponieważ twoja aplikacja nie została uruchomiona w WoW64 , ale pliki DLL muszą tam zostać uruchomione.

Jeśli skompilujesz jako x86, system x64 uruchomi aplikację w WoW64 i będziesz mógł załadować 32-bitowe pliki DLL.

Myślę więc, że powinieneś wybrać „Dowolny procesor”, jeśli twoje zależności mogą działać w dowolnym środowisku, ale wybierz x86, jeśli masz zależności 32-bitowe. W tym artykule Microsoft wyjaśnia to nieco:

/ CLRIMAGETYPE (Określ typ obrazu CLR)

Nawiasem mówiąc, ta inna dokumentacja Microsoft zgadza się, że x86 jest zwykle bardziej przenośnym wyborem:

Wybór x86 to ogólnie najbezpieczniejsza konfiguracja pakietu aplikacji, ponieważ będzie działać na prawie każdym urządzeniu. Na niektórych urządzeniach pakiet aplikacji z konfiguracją x86 nie będzie działał, na przykład Xbox lub niektóre urządzenia IoT Core. Jednak w przypadku komputerów PC pakiet x86 jest najbezpieczniejszym wyborem i ma największy zasięg wdrażania urządzeń. Znaczna część urządzeń z systemem Windows 10 nadal uruchamia wersję systemu Windows x86.

Paul A Jungwirth
źródło
2
Być może możesz edytować swoją odpowiedź, aby powiedzieć, w jaki sposób można ustalić, czy dana biblioteka DLL jest tylko 32-bitowa. O ile mi wiadomo, to powinno to zrozumieć. Myślę, że mamy nadzieję na biblioteki DLL, które są również „Dowolnymi procesorami”, a nie tylko x86.
Dan W
+1 ważne wyróżnienie. Wymagane było użycie 32-bitowej zależności (która nie została zidentyfikowana jako taka). Nie udało się rozgryźć tajemniczych komunikatów o błędach środowiska wykonawczego. Na przeczucie zmieniłem cel procesora i zadziałało, ale szukałem „dlaczego”. Kiedyś wszystko będzie 64-bitowe, a problemy z niekompatybilnością będą wydawać się dziwne, tak jak teraz 16-bitowe.
Gerald Davis,
2
@ GeraldDavis - zgadzam się. Ironia polega na tym, że nie ma technologicznego powodu, aby nie mieszać zależności 32-bitowych i 64-bitowych (po prostu brak warstwy thunking w CLR) i byłem rozczarowany na początku .NET, kiedy zobaczyłem bit- Wdrażanie wciąż było czymś do rozważenia (biorąc pod uwagę, że jest to VM / JIT, byłaby to okazja, aby zapewnić nieco więcej wartości dodanej).
codenheim
1
@mrjoltcola: Jeszcze gorsze jest to, że Microsoft zdecydował z tego powodu, że nie mogę pojąć, że wpisy rejestru powinny być podzielone na 32-bitowy i 64-bitowy wszechświat, nawet jeśli kontrolują takie rzeczy, jak kolory ekranu, ustawienia domyślne itp.
supercat
Oto odpowiedź, której szukałem ... Dzięki!
Murat z Daminion Software,
51

Oto krótki przegląd wyjaśniający różne cele kompilacji.

Z własnego doświadczenia wynika, że ​​jeśli chcesz zbudować projekt, który będzie działał zarówno na platformach x86, jak i x64, a nie masz żadnych konkretnych optymalizacji x64, zmieniłbym kompilację tak, aby zawierał „x86”.

Powodem tego jest czasem uzyskanie kolizji plików DLL lub kodu powodującego awarię WoW w środowisku x64. Określając x86, system operacyjny x64 będzie traktował aplikację jako czystą aplikację x86 i upewni się, że wszystko działa płynnie.

Dillie-O
źródło
37
Co może być okropne, jeśli piszesz w środowisku serwerowym i chcesz, aby Twoja aplikacja mogła zużywać więcej niż 2 GB pamięci. Opowiadasz się również za optymalizacjami JIT x64, które kiedyś mogą zejść na dalszy plan.
Austin Harris
Ilość problemów związanych ze środowiskiem uruchomieniowym, które miałem z kompilacjami AnyCPU, jest całym uzasadnieniem, którego potrzebowałem, aby przestać używać go jako opcji kompilacji, chyba że ktoś wyraźnie zażądał plików binarnych, które działają na obu. Przez ponad 10 lat nikt nie prosił o pliki binarne x86 na x64.
kayleeFrye_onDeck
2
„Określając x86, system operacyjny x64 będzie traktował aplikację jako czystą aplikację x86 i upewni się, że wszystko działa płynnie”. - Przepraszam, nie zgadzam się. System operacyjny x64 będzie nadal uruchamiał twoją aplikację x86 w WOW64
Mandeep Janjua
To po prostu zła rada dla kogoś, kto nie do końca rozumie, jaki będzie to miało wpływ. @AustinHarris daje świetny przykład. Wyobraź sobie, że proces roboczy jest ograniczony do zaledwie kilku GB pamięci RAM (ostatnio musiałem sobie z tym poradzić podczas produkcji).
rgoliveira
47

Zobacz artykuł Objaśnienie celu platformy Visual Studio .NET .

Domyślne ustawienie „Dowolny procesor” oznacza, że ​​zestaw będzie działał natywnie na procesorze, na którym aktualnie działa. Oznacza to, że będzie działał jako 64-bitowy na komputerze 64-bitowym i 32-bitowy na komputerze 32-bitowym. Jeśli zestaw zostanie wywołany z aplikacji 64-bitowej, będzie działał jako zestaw 64-bitowy i tak dalej.

Zgłoszono, że powyższy link jest uszkodzony, więc oto kolejny artykuł z podobnym wyjaśnieniem: Co tak naprawdę oznacza AnyCPU w .NET 4.5 i Visual Studio 11

DCNYAM
źródło
1
Uszkodzony link - przejście do zaparkowanej domeny teraz.
Jon Adams,
Dodałem link do drugiego artykułu z podobnymi informacjami. Zostawiłem pierwszy link na wypadek reaktywacji domeny.
DCNYAM,
45

Kredyt do książki „CLR przez C #” , zobacz:

Wpisz opis zdjęcia tutaj

Ivan
źródło
3
To jest najdokładniejsza odpowiedź na dzień 09.06.2018 i VS 15.8.0
Raikol Amaro
39

„Dowolny procesor” oznacza, że ​​po uruchomieniu programu .NET Framework na podstawie bitów systemu operacyjnego ustali, czy uruchomić program w wersji 32-bitowej czy 64-bitowej.

Istnieje różnica między procesorem x86 a dowolnym procesorem : w systemie x64 plik wykonywalny skompilowany dla X86 będzie działał jako plik wykonywalny 32-bitowy.

Jeśli chodzi o twoje podejrzenia, po prostu przejdź do wiersza polecenia programu Visual Studio 2008 i uruchom następujące polecenie.

dumpbin YourProgram.exe /headers

Powie Ci bitness twojego programu, a także o wiele więcej.

AngryHacker
źródło
7
Jeśli jest wbudowany w „dowolny procesor”, w nagłówkach zrzutu będzie wyświetlany jako 32-bitowy.
Kirbinator,
34

Każdy procesor oznacza, że ​​będzie działał na dowolnej platformie. Wynika to z faktu, że kod zarządzany jest podobny do Java. Pomyśl o tym jako o kompilacji do kodu bajtowego, który jest interpretowany przez .NET Framework w czasie wykonywania.

C ++ nie ma tej opcji, ponieważ jest kompilowany do kodu maszynowego specyficznego dla platformy.

Adam Tegen
źródło
12
+1 za odpowiedź na jedną część pytania, której nikt inny nie zrobił (o projektach C ++ nie posiadających AnyCPU jako opcji).
cplotts
C ++ / CLI można skompilować do kodu IL bez żadnego kodu maszynowego (/ clr: pure). Ale sizeof (void *) wciąż musi być stałą czasową kompilacji w C ++; więc nawet jeśli nie jest zaangażowany kod maszynowy, nadal nie można utworzyć pliku binarnego, który działałby jednocześnie na 32-bitowym i 64-bitowym.
Daniel
5

Polecam przeczytanie tego postu .

Podczas korzystania z AnyCPU semantyka jest następująca:

  • Jeśli proces działa w 32-bitowym systemie Windows, działa jako proces 32-bitowy. CIL jest kompilowany do kodu maszynowego x86.
  • Jeśli proces działa w 64-bitowym systemie Windows, działa jako proces 32-bitowy. CIL jest kompilowany do kodu maszynowego x86.
  • Jeśli proces działa w systemie ARM Windows, działa jako proces 32-bitowy. CIL jest kompilowany do kodu maszynowego ARM.
mamczas
źródło
8
Tylko jeśli wybrano „Preferuj 32-bit”.
Florian Winter,
Który jest domyślny od Visual Studio 11
Moerwald
@Moerwald Uważam, że to błąd, który został naprawiony. Jeśli czytasz post, do którego odwołuje się mamczas, autor pisze „w bieżącym interfejsie Visual Studio UI„ Preferuj 32-bit ”jest wyszarzony i odznaczony, gdzie w rzeczywistości jest włączony…”; W mojej wersji VS (15.8.0) opcja jest nadal wyszarzona i odznaczona, jednak działa zgodnie z oczekiwaniami (flaga 32BITPREF = FAŁSZ w sekcji CorFlags skompilowanego zestawu)
Raikol Amaro
-1

Tak to zrobiłem w Visual Studio 2017:

  • W Eksploratorze rozwiązań
  • Kliknij projekt prawym przyciskiem myszy
  • Kliknij „Właściwości”
  • Kliknij „Build”
  • Wyłącz opcję „Preferuj wersję 32-bitową”
  • I możesz wybrać „x64” z celu platformy.
M. Fawad Surosh
źródło
Ta odpowiedź jest nie na temat.
Jonas