¿Qué significa el objetivo de Visual Studio "Any CPU"?

496

Tengo cierta confusión relacionada con las opciones de compilación de la plataforma .NET en Visual Studio 2008.

¿Cuál es el objetivo de compilación "Cualquier CPU" y qué tipo de archivos genera? Examiné el ejecutable de salida de esta compilación "Cualquier CPU" y descubrí que son ejecutables x86 (¡quién no lo vería venir!). Entonces, ¿hay alguna diferencia entre apuntar ejecutable a x86 frente a "Any CPU"?

Otra cosa que noté es que los proyectos administrados de C ++ no tienen esta plataforma como una opción. ¿Porqué es eso? ¿Eso significa que mi sospecha acerca de que los ejecutables de "Cualquier CPU" son simples de 32 bits es correcta?

galets
fuente
44
Una cosa más a tener en cuenta a la hora de decidir qué objetivo de plataforma utilizar: si el objetivo del proyecto de inicio es Any CPUy se está ejecutando en un sistema operativo de 64 bits, pierde la capacidad de editar y continuar durante la depuración. (Estás depurando efectivamente un proceso de 64 bits). Puede hacer que el objetivo del proyecto de iniciox86 evite esto mientras se depura. (Las asambleas a las que se hace referencia en el proyecto de inicio pueden continuar apuntando Any CPU.
Cristian Diaconescu
8
@CristiDiaconescu con VS2013 Editar y continuar ahora es posible
ms007
Creo que debería haber alguna nota aquí sobre si el proyecto es una aplicación o una biblioteca de clases, ya que establecer el bitness objetivo para este último puede afectar su disponibilidad para las aplicaciones consumidoras dependiendo de la plataforma. Me encontré con esto con una x86biblioteca consumida por una AnyCPUaplicación donde tuve que configurarla Prefer 32-bitpara evitar un error de carga.
SteveCinq

Respuestas:

386

Un ensamblaje AnyCPU JITARÁ en código de 64 bits cuando se cargue en un proceso de 64 bits y 32 bits cuando se cargue en un proceso de 32 bits.

Al limitar la CPU, estaría diciendo: el ensamblaje está utilizando algo (algo probablemente no administrado) que requiere 32 bits o 64 bits.

AnthonyWJones
fuente
3
Entonces, ¿cómo produzco el ensamblaje que JIT a x64 en C ++?
galets
50
Los proyectos de C ++ se compilan en código nativo, por lo que el compilador JIT no está involucrado ... por lo tanto, no puede hacer lo que está pidiendo.
cplotts
77
@cplotts: dado que @galets hizo esta pregunta hace 3 meses, es poco probable que vea tu respuesta. Use el prefijo @galets en su comentario similar a como lo tengo aquí para que reciba una alerta sobre su respuesta.
AnthonyWJones
44
@AnthonyWJones En general, tienes razón, excepto cuando el usuario es el OP de la pregunta, como en este caso, ya que recibirán notificaciones de todos los comentarios.
Mark Hurd
12
@MarkHurd En realidad, en este caso, el OP no será notificado. Los OP no reciben notificaciones de comentarios a respuestas a menos que estén específicamente vinculados con la sintaxis @. Los OP solo reciben notificaciones automáticas de los comentarios agregados a su pregunta original.
RSW
322

Creo que se ha dicho la mayoría de las cosas importantes, pero solo pensé en agregar una cosa: si compila como Any CPU y se ejecuta en una plataforma x64, entonces no podrá cargar archivos DLL de 32 bits, porque su aplicación no se inició en WoW64 , pero esos archivos DLL deben ejecutarse allí.

Si compila como x86, entonces el sistema x64 ejecutará su aplicación en WoW64 y podrá cargar archivos DLL de 32 bits.

Así que creo que debería elegir "Cualquier CPU" si sus dependencias pueden ejecutarse en cualquier entorno, pero elija x86 si tiene dependencias de 32 bits. Este artículo de Microsoft explica esto un poco:

/ CLRIMAGETYPE (Especifique el tipo de imagen CLR)

Por cierto, esta otra documentación de Microsoft está de acuerdo en que x86 suele ser una opción más portátil:

Elegir x86 es generalmente la configuración más segura para un paquete de aplicaciones, ya que se ejecutará en casi todos los dispositivos. En algunos dispositivos, no se ejecutará un paquete de aplicaciones con la configuración x86, como Xbox o algunos dispositivos IoT Core. Sin embargo, para una PC, un paquete x86 es la opción más segura y tiene el mayor alcance para la implementación del dispositivo. Una parte sustancial de los dispositivos con Windows 10 continúa ejecutando la versión x86 de Windows.

Paul A Jungwirth
fuente
2
Quizás pueda editar su respuesta para decir cómo se puede determinar si una DLL determinada es solo de 32 bits. Que yo sepa, esto debería resolverlo. Creo que esperamos archivos DLL que también sean "Cualquier CPU", en lugar de solo x86.
Dan W
+1 una distinción importante. Se requirió el uso de una dependencia de 32 bits (que no se identificó como tal). No se pudieron descifrar los mensajes de error de tiempo de ejecución críptico. En una corazonada cambió el objetivo de la CPU y funcionó pero buscó "por qué". Será bueno algún día cuando todo sea de 64 bits y los problemas de incompatibilidad parezcan curiosos, como ahora es de 16 bits frente a 32 bits.
Gerald Davis
2
@GeraldDavis - Estoy de acuerdo. La ironía es que no hay una razón tecnológica para no poder mezclar dependencias de 32 bits y 64 bits (solo la falta de una capa de thunking en el CLR) y me decepcioné en los primeros días de .NET cuando vi bit- Todavía era algo a tener en cuenta al implementar (considerando que se trata de una VM / JIT, habría sido una oportunidad para proporcionar un poco más de valor agregado).
Codenheim
1
@mrjoltcola: incluso peor que esa es la forma en que Microsoft decidió por una razón por la que no puedo entender que las entradas del registro se dividan en un universo de 32 bits y 64 bits, incluso si controlan cosas como los colores de la pantalla, la configuración predeterminada, etc.
supercat
Esta es la respuesta que estaba buscando ... ¡Gracias!
Murat de Daminion Software
52

Aquí hay una descripción general rápida que explica los diferentes objetivos de compilación.

Desde mi propia experiencia, si está buscando construir un proyecto que se ejecute en plataformas x86 y x64, y no tiene optimizaciones específicas de x64, cambiaría la construcción para decir específicamente "x86".

La razón de esto es que a veces puede obtener algunos archivos DLL que colisionan o algún código que termina bloqueando WoW en el entorno x64. Especificando específicamente x86, el sistema operativo x64 tratará la aplicación como una aplicación pura x86 y se asegurará de que todo funcione sin problemas.

Dillie-O
fuente
37
Lo que podría ser terrible si está escribiendo para un entorno de servidor y desea que su aplicación pueda usar más de 2 GB de memoria. También está optando por dejar de lado las optimizaciones JIT x64 que algún día puedan surgir.
Austin Harris
La cantidad de problemas de tiempo de ejecución que he tenido con las compilaciones de AnyCPU es toda la justificación que he necesitado para dejar de usarla como una opción de compilación a menos que alguien haya solicitado explícitamente archivos binarios que funcionen en ambos. No he tenido a nadie que solicite binarios x86 sobre x64 para nada en más de 10 años.
kayleeFrye_onDeck
2
"Especificando específicamente x86, el sistema operativo x64 tratará la aplicación como una aplicación pura x86 y se asegurará de que todo funcione sin problemas". - Lo siento, no estoy de acuerdo. x64 OS seguirá ejecutando su aplicación x86 dentro de un WOW64
Mandeep Janjua
Este es solo un mal consejo para alguien que no comprende completamente el impacto que tendrá. @AustinHarris da un gran ejemplo. Imagine un proceso de trabajo web limitado a solo unos pocos GB de RAM (recientemente tuve que lidiar con esto en producción).
rgoliveira
47

Consulte el artículo Visual Studio .NET Platform Target Explicado .

La configuración predeterminada, "Cualquier CPU", significa que el ensamblaje se ejecutará de forma nativa en la CPU en la que se está ejecutando actualmente. Es decir, se ejecutará como 64 bits en una máquina de 64 bits y 32 bits en una máquina de 32 bits. Si se llama al ensamblado desde una aplicación de 64 bits, funcionará como un ensamblaje de 64 bits, etc.

Se ha informado que el enlace anterior está roto, por lo que aquí hay otro artículo con una explicación similar: lo que realmente significa AnyCPU a partir de .NET 4.5 y Visual Studio 11

DCNYAM
fuente
1
Enlace roto: ir a un dominio estacionado ahora.
Jon Adams
Agregué un enlace a un segundo artículo con información similar. Dejé el primer enlace en caso de que ese dominio se reactive alguna vez.
DCNYAM
46

Crédito al libro "CLR vía C #" , vea esto:

Ingrese la descripción de la imagen aquí

Ivan
fuente
3
Esta es la respuesta más precisa a partir del 06/09/2018 y VS 15.8.0
Raikol Amaro
39

"Cualquier CPU" significa que cuando se inicia el programa, .NET Framework determinará, en función del bit del sistema operativo, si ejecutar su programa en 32 bits o 64 bits.

Hay una diferencia entre x86 y cualquier CPU : en un sistema x64, su ejecutable compilado para X86 se ejecutará como un ejecutable de 32 bits.

En cuanto a sus sospechas, simplemente vaya a la línea de comandos de Visual Studio 2008 y ejecute lo siguiente.

dumpbin YourProgram.exe /headers

Le dirá la bondad de su programa, además de mucho más.

AngryHacker
fuente
77
Si está integrado en "cualquier CPU", se mostrará como 32 bits en los encabezados del basurero.
Kirbinator
34

Cualquier CPU significa que funcionará en cualquier plataforma. Esto se debe a que el código administrado es similar a Java. Piense que está compilado en un código de bytes interpretado por .NET Framework en tiempo de ejecución.

C ++ no tiene esta opción porque está compilada en código de máquina que es específico de la plataforma.

Adam Tegen
fuente
12
+1 por responder la parte de la pregunta que nadie más hizo (sobre los proyectos de C ++ que no tienen AnyCPU como opción).
cplotts
C ++ / CLI se puede compilar en código IL sin ningún código de máquina (/ clr: pure). Pero sizeof (void *) todavía necesita ser una constante de tiempo de compilación en C ++; así que incluso cuando no hay ningún código de máquina involucrado, aún no puede crear un binario que funcione en 32 bits y 64 bits al mismo tiempo.
Daniel
5

Recomiendo leer esta publicación .

Al usar AnyCPU , la semántica es la siguiente:

  • Si el proceso se ejecuta en un sistema Windows de 32 bits, se ejecuta como un proceso de 32 bits. CIL se compila en código de máquina x86.
  • Si el proceso se ejecuta en un sistema Windows de 64 bits, se ejecuta como un proceso de 32 bits. CIL se compila en código de máquina x86.
  • Si el proceso se ejecuta en un sistema ARM de Windows, se ejecuta como un proceso de 32 bits. CIL se compila en el código de máquina ARM.
mamczas
fuente
8
Solo si se selecciona "Preferir 32 bits".
Florian Winter
Cuál es el valor predeterminado desde Visual Studio 11
Moerwald
@ Moerwald Creo que fue un error que se ha solucionado. Si lee la publicación a la que hace referencia mamczas, el autor escribe "en la interfaz de usuario actual de Visual Studio" Preferir 32 bits "está atenuado y desmarcado, donde en realidad está habilitado ..."; En mi versión de VS (15.8.0) la opción todavía está atenuada y desmarcada, sin embargo, funciona como se esperaba (flag 32BITPREF = FALSE en la sección CorFlags del ensamblado compilado)
Raikol Amaro