Como: Migrar para /clr
Este tópico aborda problemas que surgem durante a compilação de código nativo com /clr (consulte /CLR (common Language Runtime Compilation) para obter mais informações)./clrpermite que os módulos do Visual C++ chamar e ser chamado de.NET assemblies mantendo a compatibilidade com módulos não gerenciados.Consulte Mistos Assemblies (nativos e gerenciados) e Nativa e.Interoperabilidade. para obter mais informações sobre as vantagens de compilação com /clr.
Conhecido problemas compilação biblioteca projetos com /CLR.
Visual Studio contém alguns problemas conhecidos durante a compilação de projetos de biblioteca com /clr:
Seu código pode consultar tipos em tempo de execução com CRuntimeClass::FromName.No entanto, se um tipo estiver em uma. dll MSIL (compilado com /clr), a chamada para CRuntimeClass::FromName pode falhar se ele ocorre antes de executar os construtores estáticos na. dll gerenciado (você não verá esse problema se a chamada FromName acontecer após execução do código no arquivo. dll gerenciado).Para contornar esse problema, você pode forçar a construção do construtor estático gerenciado definindo uma função na DLL gerenciada, exportá-lo e invocar o do aplicativo nativo do MFC.Por exemplo:
// Extension DLL Header file: __declspec( dllexport ) void EnsureManagedInitialization () { // managed code that won't be optimized away System::GC::KeepAlive(System::Int32::MaxValue); }
Compilar com o Visual C++
Antes de usar /clr em qualquer módulo no seu projeto, primeiro compilar e vincular o projeto nativo com Visual Studio 2010.
As seguintes etapas seguidas na ordem, fornecem o caminho mais fácil para um /clr compilação.É importante compilar e executar seu projeto após cada uma dessas etapas.
Versões anteriores ao Visual C++ 2003
Se você estiver atualizando para Visual Studio 2010 de uma versão anterior ao Visual C++ 2003, você poderá ver erros de compilador relacionados para a conformidade de padrão C++ avançada no Visual C++ 2003
Atualizando do Visual C++ 2003
Projetos anteriores criados com Visual C++ 2003 também primeiro devem ser compilados sem /clr como Visual Studio agora tem maior conformidade ANSI/ISO e algumas alterações significativas.A alteração é provável que exigem mais atenção é Recursos de segurança no CRT.Código que usa a CRT é muito provável gerar avisos de substituição.Esses avisos podem ser suprimidas, mas a migração para o novo Versões de segurança avançada de funções CRT é preferido, pois eles fornecem melhor segurança e podem revelar problemas de segurança em seu código.
Atualização do Managed Extensions for C++
Projetos criados com Visual C++.NET ou Visual C++ 2003 usado Managed Extensions for C++ requer pelo menos uma alteração nas configurações de projeto, como essas extensões são agora desaprovadas.Como resultado, o código escrito com Managed Extensions for C++ não compila em /clr.Use /clr:oldSyntax em vez disso.
Converter o código c para C++
Embora Visual Studio irá compilar arquivos C, é necessário convertê-los em C++ para um /clr compilação.Nome de arquivo real não precisa ser alterado; you can use /Tp (see / Tc, /Tp, /TC, /TP (Especifica o tipo de arquivo de origem).) Observe que embora os arquivos de código-fonte C++ são necessários para /clr, não é necessário re-factor seu código usar paradigmas orientados a objeto.
Código c é muito provável que exigem alterações quando compilado como um arquivo C++.As regras de segurança de tipo C++ são estritas, portanto, conversões de tipo devem ser feitas explícitas com conversões.Por exemplo, malloc retorna um ponteiro nulo, mas pode ser atribuído a um ponteiro para qualquer tipo em c com uma projeção:
int* a = malloc(sizeof(int)); // C code
int* b = (int*)malloc(sizeof(int)); // C++ equivalent
Ponteiros de função também são estritamente tipo seguro no C++, o seguinte código c requer modificação.C++ é melhor criar um typedef que define o tipo de ponteiro de função e usar esse tipo para converter ponteiros de função:
NewFunc1 = GetProcAddress( hLib, "Func1" ); // C code
typedef int(*MYPROC)(int); // C++ equivalent
NewFunc2 = (MYPROC)GetProcAddress( hLib, "Func2" );
C++ também requer que funções ser protótipo ou totalmente definido antes que possam ser referenciados ou invocados.
Identificadores utilizados no código c que são palavras-chave em C++ (como virtual, new, delete, bool, true, false, etc.) devem ser renomeados.Geralmente, isso pode ser feito com simples operações de pesquisa e substituição.
Finalmente, enquanto as chamadas COM estilo c exigem uso explícito de tabela v e this ponteiro, C++ não:
COMObj1->lpVtbl->Method(COMObj, args); // C code
COMObj2->Method(args); // C++ equivalent
Reconfigurar as configurações do projeto
Depois que o projeto compila e executa em Visual Studio 2010, você deve criar novas configurações de projeto para /clr em vez de modificar as configurações padrão./clré incompatível com algumas opções de compilador e criar configurações separadas permite que você criar seu projeto como nativo ou gerenciado.Quando /clr está selecionado na caixa de diálogo propriedade páginas, configurações de projeto não é compatíveis com /clr são desativados (e opções desativadas não serão restauradas automaticamente se /clr é desmarcada posteriormente).
Criar novas configurações de projeto
Você pode usar Configurações de cópia de a opção do Caixa de diálogo de configuração do novo projeto para criar uma configuração de projeto com base em suas configurações de projeto existente.Fazer isso vez para a configuração de depuração e uma vez para a configuração de versão.Alterações subseqüentes podem ser aplicadas ao /clr -configurações específicas, deixando as configurações do projeto original intacto.
Projetos que usam regras de compilação personalizada podem exigir atenção extra.
Essa etapa tem implicações diferentes para projetos que usam makefiles.Neste caso, um destino de compilação separado pode ser configurado ou versão específica para /clr compilação pode ser criada a partir de uma cópia do original.
Alterar as configurações de projeto
/clrpode ser selecionado no ambiente de desenvolvimento, seguindo as instruções em /CLR (common Language Runtime Compilation).Como mencionado anteriormente, esta etapa automaticamente desativará configurações conflitantes do projeto.
Observação |
---|
Ao atualizar um projeto de serviço web ou uma biblioteca gerenciada do Visual C++ 2003, o /Zl será de opção de compilador adicionada ao linha de comando página de propriedade.Isso fará com que LNK2001.Remover /Zl do linha de comando página de propriedade para resolver.Consulte /ZL (omitir o nome da biblioteca padrão) e Como: abrir páginas de propriedades do projeto para mais informações.Ou, adicione msvcrt.lib e msvcmrt.lib para o vinculador Dependências adicionais propriedade. |
Para projetos criados com makefiles, opções de compilador incompatível devem ser desativadas manualmente uma vez /clr é adicionado.Consulte //CLR restrições para obter informações sobre opções de compilador que não são compatíveis com /clr.
Cabeçalhos pré-compilados
Cabeçalhos pré-compilados são suportados em /clr.No entanto, se você compilar apenas alguns arquivos CPP com /clr (compilar o restante como nativo) algumas alterações serão necessárias porque precompiled headers gerados com /clr não são compatíveis com aqueles gerados sem /clr.Essa incompatibilidade é devido ao fato de que /clr gera e requer metadados.Módulos compilados /clr , portanto, não pode usar cabeçalhos pré-compilados não incluam metadados, e não /clr módulos não é possível usar arquivos de cabeçalho pré-compilado que contêm metadados.
A maneira mais fácil de compilar um projeto onde alguns módulos são compilados /clr é desativar totalmente a cabeçalhos pré-compilados.(Na caixa de diálogo project Property Pages, abra o nó C/C++ e selecionar cabeçalhos pré-compilados.Alterar a propriedade de Create/Use Precompiled Headers para "Not Using Precompiled Headers".)
No entanto, especialmente para projetos grandes, cabeçalhos pré-compilados fornecem muito melhor velocidade de compilação, desativar esse recurso não é desejável.Nesse caso é melhor configurar o /clr e não /clr arquivos para usar cabeçalhos pré-compilados separados.Isso pode ser feito em uma etapa por multi-selecting os módulos a serem compilados /clr usando o Solution Explorer, clicando com o botão direito no grupo e selecionando Propriedades.Altere propriedades de criar/usar PCH através de arquivo e o arquivo de cabeçalho pré-compilado para usar um nome de arquivo de cabeçalho diferente e o arquivo PCH respectivamente.
Corrigindo erros
Compilando com /clr pode resultar em erros de compilador, vinculador ou tempo de execução.Esta seção aborda os problemas mais comuns.
Metadados de mesclagem
Versões diferentes de tipos de dados podem causar o vinculador falha porque os metadados gerado para os dois tipos não correspondem.(Isso geralmente é causado quando os membros de um tipo condicionalmente são definidos, mas as condições não são iguais para todos os arquivos CPP que usam o tipo.) Nesse caso o vinculador falha, relatórios somente o nome do símbolo e o nome do segundo arquivo OBJ onde o tipo foi definido.Geralmente é útil girar a ordem em que os arquivos OBJ são enviados para o vinculador para descobrir a localização da versão do tipo de dados.
Bloqueio de bloqueio de carregador
No Visual C++.NET e Visual C++ 2003, inicialização em /clr foi suscetível a bloqueio não-determinístico.Esse problema é conhecido como "bloqueio de bloqueio de carregador".Em 2010 Visual Studio, é mais fácil evitar esse deadlock, é detectado e reportado em tempo de execução e não é não-determinística.Encontrar o problema de bloqueio do carregador é ainda possível, mas agora é muito mais fácil evitar e corrigir.Consulte Inicialização de Assemblies mistos detalhadas, orientação e soluções.
Exportações de dados
Exportando dados DLL é propenso a erros e não recomendável.Isso ocorre porque a seção de dados de uma DLL não é garantida para ser inicializado até que alguma parte gerenciado da DLL foi executado.Metadados de referência com # usando diretiva (C++).
Visibilidade de tipo
Tipos nativos agora são particulares por padrão.No Visual C++.NET 2002 e Visual C++ 2003, tipos nativos eram públicos por padrão.Isso pode resultar em um tipo nativo não sendo visíveis fora da DLL.Resolver esse erro, adicionando public a esses tipos.Consulte Visibilidade do tipo e do membro para maiores informações.
Flutuante ponto e problemas de alinhamento
__controlfpNão há suporte para o common language runtime (consulte _control87, _controlfp, __control87_2 para obter mais informações).O CLR também respeitam não Alinhar (C++).
Inicialização de COM
O Common Language Runtime inicializa COM automaticamente quando um módulo é inicializado (quando COM é inicializado automaticamente ele tem feito isso como MTA).Como resultado, inicializar explicitamente COM gera códigos de retorno indicando que COM já foi inicializada.Tentar inicializar explicitamente COM um modelo de threading quando o CLR já foi inicializado COM para outro modelo de threading pode causar o aplicativo falhar.
O common language runtime começa COM como MTA por padrão; Use / CLRTHREADATTRIBUTE (atributo definir CLR Thread) para modificar isso.
Problemas de desempenho
Você pode ver uma redução no desempenho quando métodos C++ nativos gerados para MSIL forem chamados indiretamente (chamadas de função virtual ou usando ponteiros de função).Para saber mais sobre isso, consulte Duplo conversão (C++).
Ao mover de nativo para MSIL, você observará um aumento no tamanho do seu conjunto de trabalho.Isso ocorre porque o common language runtime fornece muitos recursos para garantir que os programas sejam executados corretamente.Se o /clr aplicativo não está funcionando corretamente, talvez você queira habilitar C4793 (desativado por padrão), consulte C4793 de aviso (nível 1 e 3) do compilador para obter mais informações.
Programa falha no desligamento
Em alguns casos, o CLR pode desligamento antes de termina seu código gerenciado em execução.Usando std::set_terminate e SIGTERM pode causar esse problema.Consulte Constantes de sinal e set_terminate (<exception>) para mais informações.
Usando os novos recursos do Visual C++
Depois que o aplicativo compila, links e é executado, você pode começar a usar.NET recursos em qualquer módulo compilado com /clr.Para mais informações, consulte Extensões de componente para plataformas de tempo de execução.
Se você usou o Managed Extensions for C++, você pode converter seu código para usar a nova sintaxe.Para obter um resumo das diferenças sintáticas, consulte o Managed Extensions for C++ Syntax Upgrade Checklist.Para obter detalhes sobre como converter Managed Extensions for C++, consulte C + + / CLI migração Primer.
Para obter informações sobre.NET programação no Visual C++ consulte: