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.