O que significa o destino do Visual Studio "Qualquer CPU"?

496

Tenho alguma confusão relacionada às opções de compilação da plataforma .NET no Visual Studio 2008.

Qual é o destino de compilação "Qualquer CPU" e que tipo de arquivo ele gera? Examinei o executável de saída dessa compilação "Any CPU" e descobri que eles são os executáveis ​​x86 (que não esperariam isso!). Portanto, existe alguma diferença entre direcionar executável para x86 x "Qualquer CPU"?

Outra coisa que notei é que os projetos C ++ gerenciados não têm essa plataforma como opção. Por que é que? Isso significa que minha suspeita sobre os executáveis ​​de "Qualquer CPU" serem simples de 32 bits está correta?

galets
fonte
4
Mais uma coisa a considerar ao decidir qual destino de plataforma usar: se o destino do projeto Startup for Any CPUe você estiver executando em um sistema operacional de 64 bits, você perde a capacidade de editar e continuar durante a depuração. (Você está efetivamente depurando um processo de 64 bits). Você pode fazer o destino do projeto de inicializaçãox86 contornar isso durante a depuração. (Os conjuntos referenciados a partir do projecto de arranque pode continuar a alvo Any CPU.
Cristian Diaconescu
8
@CristiDiaconescu Com VS2013 Editar e continuar agora é possível
ms007
Eu acho que deveria haver alguma observação aqui sobre se o projeto é um aplicativo ou uma biblioteca de classes, pois definir o número limite de destino para este último pode afetar sua disponibilidade para consumir aplicativos, dependendo da plataforma. Eu me deparei com isso com uma x86biblioteca sendo consumida por um AnyCPUaplicativo onde eu tinha que definir Prefer 32-bitpara evitar um erro de carregamento.
SteveCinq

Respostas:

386

Um assembly AnyCPU JIT para código de 64 bits quando carregado em um processo de 64 bits e 32 bits quando carregado em um processo de 32 bits.

Ao limitar a CPU, você diria: Há algo sendo usado pelo assembly (algo provavelmente não gerenciado) que requer 32 bits ou 64 bits.

AnthonyWJones
fonte
3
então, como eu produzo um assembly que será JIT para x64 em C ++?
## galets #
50
Projetos C ++ compilam com código nativo, portanto o compilador JIT não está envolvido ... portanto, você não pode fazer o que está pedindo.
Cplotts
7
@cplotts: desde que @galets fez esta pergunta há 3 meses, é improvável que ele veja sua resposta. Use o prefixo @galets no seu comentário semelhante ao que eu tenho aqui, para que ele receba um alerta sobre sua resposta.
AnthonyWJones
4
@AnthonyWJones Em geral, você está correto, exceto onde o usuário é o OP da pergunta, como neste caso, pois eles serão notificados de todos os comentários.
Mark Hurd
12
@ MarkHurd Na verdade, nesse caso, o OP não será notificado. Os OPs não são notificados dos comentários às respostas, a menos que sejam especificamente executados ping na sintaxe @. Os OPs são notificados automaticamente apenas dos comentários adicionados à sua pergunta original.
RSW 12/07
322

Acho que a maioria das coisas importantes foi mencionada, mas pensei em acrescentar uma coisa: se você compilar como Qualquer CPU e executar em uma plataforma x64, não poderá carregar arquivos DLL de 32 bits, porque seu aplicativo não foi iniciado no WoW64 , mas esses arquivos DLL precisam ser executados lá.

Se você compilar como x86, o sistema x64 executará seu aplicativo no WoW64 e poderá carregar arquivos DLL de 32 bits.

Portanto, acho que você deve escolher "Qualquer CPU" se suas dependências puderem ser executadas em qualquer ambiente, mas escolher x86 se tiver dependências de 32 bits. Este artigo da Microsoft explica isso um pouco:

/ CLRIMAGETYPE (especifique o tipo de imagem CLR)

Aliás, esta outra documentação da Microsoft concorda que o x86 é geralmente uma opção mais portátil:

Escolher o x86 geralmente é a configuração mais segura para um pacote de aplicativos, pois é executado em quase todos os dispositivos. Em alguns dispositivos, um pacote de aplicativos com a configuração x86 não será executado, como o Xbox ou alguns dispositivos IoT Core. No entanto, para um PC, um pacote x86 é a opção mais segura e tem o maior alcance para implantação de dispositivos. Uma parte substancial dos dispositivos Windows 10 continua executando a versão x86 do Windows.

Paul A Jungwirth
fonte
2
Talvez você possa editar sua resposta para dizer como é possível determinar se uma determinada DLL é apenas de 32 bits. Tanto quanto eu sei, isso deve descobrir isso. Acho que esperamos por DLLs que também sejam "Qualquer CPU", em vez de apenas x86.
10133 Dan W
+1 uma distinção importante. Era necessário usar uma dependência de 32 bits (que não foi identificada como tal). Não foi possível descobrir as mensagens de erro de tempo de execução enigmático. Em um palpite mudou o alvo da CPU e funcionou, mas foi procurar "por que". Será bom algum dia quando tudo estiver em 64 bits e os problemas de incompatibilidade parecerem estranhos, como 16 bits vs 32 bits agora.
Gerald Davis
2
@GeraldDavis - eu concordo. A ironia é que não há razão tecnológica para não conseguir misturar dependências de 32 e 64 bits (apenas a falta de uma camada de thunking no CLR) e fiquei decepcionado nos primeiros dias do .NET quando vi bit- Ainda era algo a considerar ao implantar (considerando que essa é uma VM / JIT, teria sido uma oportunidade de fornecer um pouco mais de valor agregado).
Codenheim
1
@mrjoltcola: Ainda pior do que isso, foi o modo como a Microsoft decidiu que não posso entender que as entradas do registro devem ser divididas em um universo de 32 e 64 bits, mesmo que eles controlem coisas como cores da tela, configurações padrão etc.
Supercat
Esta é a resposta que eu estava procurando ... Obrigado!
Murat de Daminion Software
52

Aqui está uma rápida visão geral que explica os diferentes destinos de criação.

Pela minha própria experiência, se você deseja criar um projeto que será executado nas plataformas x86 e x64 e não possui otimizações específicas para x64, eu alteraria a construção para dizer especificamente "x86".

Às vezes, a razão para isso é que você pode obter alguns arquivos DLL que colidem ou algum código que acaba causando o travamento do WoW no ambiente x64. Especificando especificamente x86, o sistema operacional x64 tratará o aplicativo como um aplicativo x86 puro e garantirá que tudo corra bem.

Dillie-O
fonte
37
O que pode ser terrível se você estiver gravando em um ambiente de servidor e desejar que seu aplicativo use mais de 2 GB de memória. Você também está optando por quaisquer otimizações de JIT x64 que algum dia possam ocorrer.
Austin Harris
A quantidade de problemas de tempo de execução que tive com as compilações do AnyCPU é toda a justificativa necessária para parar de usá-lo como uma opção de compilação, a menos que alguém tenha solicitado explicitamente binários que funcionam em ambos. Não há ninguém que solicite binários x86 acima de x64 há mais de 10 anos.
kayleeFrye_onDeck
2
"Ao especificar especificamente o x86, o sistema operacional x64 tratará o aplicativo como um aplicativo x86 puro e garantirá que tudo corra bem." Desculpe, eu discordo. x64 OS ainda será executado seu aplicativo x86 dentro de um WOW64
Mandeep Janjua
Este é apenas um mau conselho para alguém que não entende completamente o impacto que isso terá. @AustinHarris dá um ótimo exemplo. Imagine um processo de trabalho na Web limitado a apenas alguns GB de RAM (recentemente tive que lidar com isso na produção).
Rgoliveira
47

Confira o artigo Visual Studio .NET Platform Target Explained .

A configuração padrão, "Qualquer CPU", significa que o assembly será executado nativamente na CPU em que está sendo executado. Ou seja, ele será executado como 64 bits em uma máquina de 64 bits e 32 bits em uma máquina de 32 bits. Se o assembly for chamado de um aplicativo de 64 bits, ele será executado como um assembly de 64 bits e assim por diante.

O link acima foi relatado como quebrado, então aqui está outro artigo com uma explicação semelhante: O que AnyCPU realmente significa no .NET 4.5 e no Visual Studio 11

DCNYAM
fonte
1
Link quebrado - indo para um domínio estacionado agora.
John Adams
Adicionei um link para um segundo artigo com informações semelhantes. Deixei o primeiro link para o caso de o domínio ser reativado.
DCNYAM
46

Crédito para o livro "CLR via C #" , consulte o seguinte:

Digite a descrição da imagem aqui

Ivan
fonte
3
Esta é a resposta mais precisa em 06/06/2018 e VS 15.8.0
Raikol Amaro 6/18/18
39

"Qualquer CPU" significa que, quando o programa for iniciado, o .NET Framework determinará, com base no sistema operacional, se o seu programa deve ser executado em 32 ou 64 bits.

Há uma diferença entre x86 e Qualquer CPU : em um sistema x64, o executável compilado para o X86 será executado como um executável de 32 bits.

No que diz respeito às suas suspeitas, vá para a linha de comando do Visual Studio 2008 e execute o seguinte.

dumpbin YourProgram.exe /headers

Ele lhe dirá o testemunho do seu programa, e muito mais.

AngryHacker
fonte
7
Se for construído em "qualquer CPU", aparecerá como 32 bits nos cabeçalhos de dumpbin.
Kirbinator
34

Qualquer CPU significa que funcionará em qualquer plataforma. Isso ocorre porque o código gerenciado é semelhante ao Java. Pense nisso como sendo compilado em um código de bytes que é interpretado pelo .NET Framework em tempo de execução.

O C ++ não possui essa opção porque é compilado para um código de máquina específico da plataforma.

Adam Tegen
fonte
12
+1 por responder à parte da pergunta que ninguém mais respondeu (sobre projetos em C ++ que não possuem AnyCPU como opção).
Cplotts
O C ++ / CLI pode ser compilado no código IL sem qualquer código de máquina (/ clr: pure). Mas sizeof (void *) ainda precisa ser uma constante em tempo de compilação em C ++; portanto, mesmo quando não há código de máquina envolvido, você ainda não pode criar um binário que funcione em 32 e 64 bits ao mesmo tempo.
Daniel
5

Eu recomendo a leitura deste post .

Ao usar o AnyCPU , a semântica é a seguinte:

  • Se o processo for executado em um sistema Windows de 32 bits, será executado como um processo de 32 bits. O CIL é compilado no código de máquina x86.
  • Se o processo for executado em um sistema Windows de 64 bits, será executado como um processo de 32 bits. O CIL é compilado no código de máquina x86.
  • Se o processo for executado em um sistema Windows ARM, ele será executado como um processo de 32 bits. O CIL é compilado para o código de máquina do ARM.
mamczas
fonte
8
Somente se "Preferir 32 bits" estiver selecionado.
Florian Winter
Qual é o padrão desde o Visual Studio 11
Moerwald
@ Moerwald Eu acredito que foi um bug que foi corrigido. Se você ler a postagem sobre a qual mamczas faz referência, o autor escreverá "na interface atual do Visual Studio" Prefer 32 bits "fica acinzentado e desmarcado, onde na realidade está ativado ..."; Na minha versão do VS (15.8.0) a opção ainda é acinzentado e sem controle, no entanto, ele funciona como esperado (bandeira 32BITPREF = FALSE na seção CorFlags compilado de montagem)
Raikol Amaro