Cosa significa la destinazione "Any CPU" di Visual Studio?


496

Ho un po 'di confusione legata alle opzioni di build della piattaforma .NET in Visual Studio 2008.

Qual è il target di compilazione "Qualsiasi CPU" e che tipo di file genera? Ho esaminato il file eseguibile di output di questa build "Any CPU" e ho scoperto che sono gli eseguibili x86 (che non vedrebbero che sarebbe arrivato!). Quindi, c'è qualche differenza tra il targeting eseguibile su x86 e "Qualsiasi CPU"?

Un'altra cosa che ho notato è che i progetti C ++ gestiti non hanno questa piattaforma come opzione. Perché? Ciò significa che il mio sospetto che gli eseguibili "Any CPU" siano semplici a 32 bit è giusto?


4
Un'altra cosa da considerare quando si decide quale target della piattaforma utilizzare: se l'obiettivo del progetto Startup è Any CPUe si esegue su un sistema operativo a 64 bit, si perde la possibilità di modificare e continuare durante il debug. (Stai effettivamente eseguendo il debug di un processo a 64 bit). È possibile rendere l' obiettivo del progetto di avviox86 per aggirare questo problema durante il debug. (Le assemblee referenziate dal progetto di avvio potrebbero continuare a prendere di mira Any CPU.
Cristian Diaconescu,

8
@CristiDiaconescu Con VS2013 Modifica e continua è ora possibile
ms007

Penso che ci dovrebbe essere qualche nota qui sul fatto che il progetto sia un'applicazione o una libreria di classi poiché l'impostazione del testimone di destinazione per quest'ultimo può influire sulla sua disponibilità a consumare applicazioni a seconda della piattaforma. Mi sono imbattuto in questo con una x86libreria consumata da AnyCPUun'applicazione in cui ho dovuto impostare Prefer 32-bitper evitare un errore di caricamento.
SteveCinq,

Risposte:


386

Un assembly AnyCPU eseguirà il JIT su codice a 64 bit se caricato in un processo a 64 bit e 32 bit se caricato in un processo a 32 bit.

Limitando la CPU diresti: c'è qualcosa che viene usato dall'assembly (qualcosa che probabilmente non è gestito) che richiede 32 bit o 64 bit.


3
quindi, come faccio a produrre assembly che sarà da JIT a x64 in C ++?
saluta il

50
I progetti C ++ vengono compilati in codice nativo, quindi il compilatore JIT non è coinvolto ... quindi, non puoi fare quello che stai chiedendo.
complotti

7
@cplotts: poiché @galets ha posto questa domanda 3 mesi fa è improbabile che vedrà la tua risposta. Usa il prefisso @galets nel tuo commento in modo simile a come ho qui in modo che riceva un avviso sulla tua risposta.
AnthonyWJones,

4
@AnthonyWJones In generale hai ragione, tranne dove l'utente è l'OP della domanda, come in questo caso, poiché riceveranno una notifica di tutti i commenti.
Mark Hurd,

12
@MarkHurd In realtà, in questo caso, l'OP non verrà notificato. I PO non ricevono notifiche dei commenti alle risposte a meno che non siano specificamente sottoposti a ping con la sintassi @. I PO vengono automaticamente avvisati solo dei commenti aggiunti alla loro domanda originale.
RSW,

322

Penso che la maggior parte delle cose importanti sia stata detta, ma ho pensato di aggiungere una cosa: se compili come Qualsiasi CPU ed esegui su una piattaforma x64, non sarai in grado di caricare file DLL a 32 bit, perché l'applicazione non è stata avviata in WoW64 , ma i file DLL devono essere eseguiti lì.

Se compili come x86, il sistema x64 eseguirà la tua applicazione in WoW64 e sarai in grado di caricare file DLL a 32 bit.

Quindi penso che dovresti scegliere "Qualsiasi CPU" se le tue dipendenze possono essere eseguite in entrambi gli ambienti, ma scegli x86 se hai dipendenze a 32 bit. Questo articolo di Microsoft lo spiega un po ':

/ CLRIMAGETYPE (specificare il tipo di immagine CLR)

Per inciso, questa altra documentazione Microsoft concorda sul fatto che x86 è di solito una scelta più portatile:

La scelta di x86 è generalmente la configurazione più sicura per un pacchetto di app poiché verrà eseguito su quasi tutti i dispositivi. Su alcuni dispositivi, non verrà eseguito un pacchetto di app con la configurazione x86, ad esempio Xbox o alcuni dispositivi IoT Core. Tuttavia, per un PC, un pacchetto x86 è la scelta più sicura e ha la portata maggiore per l'implementazione del dispositivo. Una parte sostanziale dei dispositivi Windows 10 continua a eseguire la versione x86 di Windows.


2
Forse puoi modificare la tua risposta per dire come si può determinare se una determinata DLL è solo a 32 bit. Per quanto ne so, questo dovrebbe capirlo. Penso che speriamo in DLL che sono anche "Any CPU", piuttosto che solo x86.
Dan W,

+1 una distinzione importante. È stato richiesto di utilizzare una dipendenza a 32 bit (che non è stata identificata come tale). Impossibile capire i messaggi di errore di runtime criptici. In un sospetto ha cambiato l'obiettivo della CPU e ha funzionato, ma è andato alla ricerca di "perché". Sarà bello un giorno quando tutto sarà a 64 bit e i problemi di incompatibilità sembreranno singolari come 16 bit contro 32 bit ora.
Gerald Davis,

2
@GeraldDavis - Sono d'accordo. L'ironia è che non esiste alcun motivo tecnologico per non essere in grado di mescolare dipendenze a 32 e 64 bit (solo la mancanza di un livello thunking nel CLR) e sono rimasto deluso ai primi tempi di .NET quando ho visto bit- La sicurezza era ancora qualcosa da considerare durante l'implementazione (considerando che si tratta di una VM / JIT sarebbe stata un'opportunità per fornire un po 'più di valore aggiunto).
codenheim,

1
@mrjoltcola: Peggio ancora, è il modo in cui Microsoft ha deciso per il motivo per cui non riesco a capire che le voci del registro dovrebbero essere divise in un universo a 32 e 64 bit anche se controllano cose come i colori dello schermo, le impostazioni predefinite, ecc.
supercat,

Questa è la risposta che stavo cercando ... Grazie!
Murat di Daminion Software il

52

Ecco una rapida panoramica che spiega i diversi target di build.

Dalla mia esperienza, se stai cercando di costruire un progetto che verrà eseguito su entrambe le piattaforme x86 e x64 e non hai alcuna ottimizzazione x64 specifica, cambierei la build per dire specificamente "x86".

La ragione di ciò è che a volte è possibile ottenere alcuni file DLL che si scontrano o del codice che finisce per arrestare WoW in crash nell'ambiente x64. Specificando specificamente x86, il sistema operativo x64 tratterà l'applicazione come un'applicazione pura x86 e si assicurerà che tutto funzioni senza intoppi.


37
Il che potrebbe essere terribile se si scrive per un ambiente server e si desidera che l'applicazione sia in grado di utilizzare più di 2 GB di memoria. Stai anche rifiutando qualsiasi ottimizzazione JIT x64 che un giorno potrebbe venire fuori dalla pipa.
Austin Harris,

La quantità di problemi di runtime che ho avuto con le compilazioni AnyCPU è tutta la giustificazione di cui ho bisogno per smettere di usarla come opzione di compilazione a meno che qualcuno non abbia esplicitamente richiesto binari che funzionano su entrambi. Non ho avuto nessuno che richiedesse binari x86 su x64 per nulla da oltre 10 anni.
kayleeFrye_onDeck,

2
"Specificando specificamente x86, il sistema operativo x64 tratterà l'app come un'app x86 pura e si assicurerà che tutto funzioni senza intoppi." - Mi dispiace, non sono d'accordo. Il sistema operativo x64 eseguirà comunque l'app x86 all'interno di un WOW64
Mandeep Janjua,

Questo è solo un cattivo consiglio a qualcuno che non capisce completamente l'impatto che avrà. @AustinHarris fa un grande esempio. Immagina un processo di web worker limitato a pochi GB di RAM (di recente ho dovuto occuparmene in fase di produzione).
rgoliveira,

47

Consulta l'articolo Spiegazione della destinazione della piattaforma di Visual Studio .NET .

L'impostazione predefinita, "Qualsiasi CPU", significa che l'assembly verrà eseguito in modo nativo sulla CPU su cui è attualmente in esecuzione. Ciò significa che verrà eseguito come 64 bit su un computer a 64 bit e 32 bit su un computer a 32 bit. Se l'assembly viene chiamato da un'applicazione a 64 bit, verrà eseguito come assembly a 64 bit e così via.

È stato segnalato che il collegamento sopra riportato non funziona, quindi ecco un altro articolo con una spiegazione simile: Cosa significa AnyCPU a partire da .NET 4.5 e Visual Studio 11


1
Collegamento interrotto: ora vai a un dominio parcheggiato.
Jon Adams il

Ho aggiunto un collegamento a un secondo articolo con informazioni simili. Ho lasciato il primo link nel caso in cui quel dominio fosse mai riattivato.
DCNYAM,


39

"Qualsiasi CPU" significa che all'avvio del programma, .NET Framework capirà, in base al sistema operativo testimone, se eseguire il programma in 32 bit o 64 bit.

C'è una differenza tra x86 e Any CPU : su un sistema x64, l'eseguibile compilato per X86 verrà eseguito come eseguibile a 32 bit.

Per quanto riguarda i tuoi sospetti, vai alla riga di comando di Visual Studio 2008 ed esegui quanto segue.

dumpbin YourProgram.exe /headers

Ti dirà il testimone del tuo programma, e molto altro ancora.


7
Se è incorporato in "any cpu", verrà visualizzato come 32 bit nelle intestazioni di dumpbin.
Kirbinator,

34

Qualsiasi CPU significa che funzionerà su qualsiasi piattaforma. Questo perché il codice gestito è simile a Java. Consideralo come compilato in un codice byte interpretato da .NET Framework in fase di esecuzione.

C ++ non ha questa opzione perché è compilata per codice macchina specifico della piattaforma.


12
+1 per rispondere a una parte della domanda che nessun altro ha fatto (sui progetti C ++ che non hanno AnyCPU come opzione).
complotti

C ++ / CLI può essere compilato in codice IL senza alcun codice macchina (/ clr: pure). Ma sizeof (void *) deve ancora essere una costante di compilazione in C ++; quindi anche quando non è coinvolto alcun codice macchina, non è ancora possibile creare un file binario che funzioni contemporaneamente a 32 e 64 bit.
Daniel,

5

Consiglio di leggere questo post .

Quando si utilizza AnyCPU , la semantica è la seguente:

  • Se il processo viene eseguito su un sistema Windows a 32 bit, viene eseguito come processo a 32 bit. CIL viene compilato in codice macchina x86.
  • Se il processo viene eseguito su un sistema Windows a 64 bit, viene eseguito come processo a 32 bit. CIL viene compilato in codice macchina x86.
  • Se il processo viene eseguito su un sistema ARM Windows, viene eseguito come processo a 32 bit. CIL viene compilato in base al codice macchina ARM.

8
Solo se è selezionato "Prefer 32 bit".
Florian Winter,

Qual è l'impostazione predefinita da Visual Studio 11
Moerwald

@Moerwald Credo che sia stato corretto un bug. Se leggi il post a cui fa riferimento mamczas, l'autore scrive "nell'interfaccia utente di Visual Studio corrente" Prefer 32 bit "è disattivato e deselezionato, dove in realtà è abilitato ..."; Nella mia versione di VS (15.8.0) l'opzione è ancora disattivata e deselezionata, tuttavia funziona come previsto (flag 32BITPREF = FALSE nella sezione CorFlags dell'assembly compilato)
Raikol Amaro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.