Compartilhar via


Como: Migrar para /clr

Este tópico discute os problemas que possam surgir 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 de Visual C++ invocar e ser chamado do.NET assemblies mantendo a compatibilidade com os módulos de não gerenciados. Consulte Mistos de Assemblies (nativos e gerenciados) e Nativo e.NET interoperabilidade para obter mais informações sobre as vantagens da compilação com /clr.

Conhecidos problemas compilando projetos de biblioteca com o /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 do MSIL (compilado com /clr), a chamada para CRuntimeClass::FromName pode falhar caso ele ocorra antes dos construtores estáticos são executados na gerenciado. dll (você não verá esse problema se a chamada de FromName acontece depois que o código for executado 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 gerenciado, exportá-la e invocar o do aplicativo MFC nativo. For example:

    // 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 seu projeto nativo com 2010 de Visual Studio.

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 do Visual C++ 2003

Se você estiver atualizando a 2010 de Visual Studio de uma versão anterior para o Visual C++ 2003, você poderá ver os erros de compilador relacionados para a conformidade aprimorada de padrão C++ 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 agora o Visual Studio aumentou de conformidade ANSI/ISO e algumas alterações mais recentes. A alteração que provavelmente exigem mais atenção é Security Enhancements in the CRT. Código que usa a CRT é muito provável que produzem avisos de substituição. Esses avisos podem ser suprimida, mas a migração para o novo Security-Enhanced Versions of CRT Functions é o preferido, pois eles fornecem melhor segurança e podem revelar problemas de segurança no seu código.

Atualizando a partir de Managed Extensions for C++

Projetos criados com Visual C++.NET ou Visual C++ 2003 usado Managed Extensions for C++ exigirá a 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 será compilado em /clr. Use /clr:oldSyntax em vez disso.

Converter o código c para C++

Embora o Visual Studio irá compilar arquivos C, é necessário convertê-los em C++ para um /clr compilação. O nome do arquivo real não precisa ser alterado; Você pode usar /Tp (consulte / 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, mas não é necessária re-factor o seu código para usar paradigmas orientada a objeto.

Código c é muito provável que exigem alterações quando compilado como um arquivo do C++. As regras de segurança de tipo C++ são rigorosas, para que as conversões de tipo devem ser feitas explícitas com projeçõ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 então 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.

Usado no código c de identificadores que são palavras-chave em C++ (como virtual, new, delete, bool, true, false, etc.) devem ser renomeados. Geralmente, isso pode ser feito com operações de pesquisa e substituição simples.

Finalmente, enquanto as chamadas estilo C COM exigem o uso explícito da tabela-v e this o 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 seu projeto compila e executa em 2010 de Visual Studio, 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ê crie seu projeto como nativo ou gerenciado. Quando /clr está selecionada na caixa de diálogo de páginas de propriedade, as 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 é subseqüentemente desmarcada).

Criar novas configurações de projeto

Você pode usar Configurações de cópia de a opção do Caixa de Diálogo New Project Configuration 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 configuração de lançamento. 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.

Esta etapa tem implicações de diferentes para projetos que usam os 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 será desativado automaticamente configurações conflitantes do projeto.

ObservaçãoObservação

Ao atualizar uma biblioteca gerenciada ou um projeto de serviço da web a partir do Visual C++ 2003, o /Zl será de opção de compilador adicionado para o linha de comando página de propriedades. Isso fará com que o LNK2001. Remover /Zl partir do a linha de comando página de propriedades para resolver. See /ZL (omitir o nome da biblioteca padrão) and Como: Abrir páginas de propriedades do projeto for more information. Ou então, adicionar 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 é adicionada. Consulte //CLR restrições para obter informações sobre opções do compilador não compatíveis com a /clr.

Cabeçalhos pré-compilados

Cabeçalhos pré-compilados são suportados em /clr. No entanto, se você compilar apenas alguns de seus arquivos CPP com /clr (o restante como nativo de compilação) algumas alterações serão necessárias porque os cabeçalhos pré-compilados gerado 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 é possível usar cabeçalhos pré-compilados que não incluem metadados, e não /clr módulos não é possível usar os arquivos de cabeçalho pré-compilado que contêm metadados.

A maneira mais fácil de compilar um projeto no qual 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 selecione cabeçalhos pré-compilados. Em seguida, altere a propriedade Create/Use Precompiled Headers para "Not Using Precompiled Headers".)

No entanto, especialmente para projetos grandes, cabeçalhos pré-compilados oferecem velocidade de compilação muito melhor para que desabilitar esse recurso não é desejável. Nesse caso é melhor configurar o /clr e não /clr arquivos para usar cabeçalhos pré-compilados separado. 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 as propriedades a criar/usar PCH através do arquivo e o arquivo de cabeçalho pré-compilado para usar um nome de arquivo de cabeçalho diferente e um arquivo PCH, respectivamente.

Corrigindo erros

Compilando com /clr pode resultar no compilador, vinculador ou erros de tempo de execução. Esta seção discute os problemas mais comuns.

Metadados de mesclagem

Versões diferentes de tipos de dados podem causar o vinculador falhe, pois não coincide com os metadados gerados para os dois tipos. (Isso é normalmente causado quando os membros de um tipo condicionalmente são definidos, mas as condições não são as mesmas para todos os arquivos CPP que usam o tipo.) Nesse caso o vinculador falha, a emissão de relatórios somente o nome de símbolo e o nome do segundo arquivo OBJ onde o tipo foi definido. Muitas vezes é ú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 do carregador

No Visual C++.NET e Visual C++ 2003 inicialização sob /clr foi suscetível a não-determinística deadlock. Esse problema é conhecido como "bloqueio de bloqueio de carregador". Em 2010 Visual Studio, esse deadlock é mais fácil evitar, ele é detectado e reportado em tempo de execução e não é mais não-determinística. Encontrar o problema de bloqueio de carregador ainda é possível, mas agora é muito mais fácil evitar e corrigir. Consulte Inicialização de Assemblies mistos para o plano de fundo detalhado, orientação e soluções.

Exportações de dados

Exportar dados da DLL está sujeito 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. Os metadados de referência com The #using Directive.

Visibilidade de tipo

Tipos nativos agora são privados por padrão. No Visual C++.NET 2002 e Visual C++ 2003, os 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 para esses tipos. See Type and Member Visibility for more information.

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 não respeitará align (C++).

Inicialização de COM

O Common Language Runtime inicializa COM automaticamente quando um módulo é inicializado (quando o COM é inicializado automaticamente ele tem feito isso como MTA). Como resultado, explicitamente Inicializando COM gera códigos de retorno indicando que COM já foi inicializada. Tentando inicializar explicitamente COM um modelo de threading, quando o CLR já inicializado COM outro modelo de threading pode fazer com que o aplicativo falhar.

O common language runtime começa COM como MTA por padrão. Use / CLRTHREADATTRIBUTE (atributo do segmento CLR do conjunto) para modificar isso.

Problemas de desempenho

Você pode ver uma redução no desempenho quando métodos nativos do C++ gerados para MSIL são chamados indiretamente (chamadas de função virtual ou usando os ponteiros de função). Para saber mais sobre isso, consulte Dupla de conversão (C++).

Ao mover de nativo para MSIL, você notará 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 sua /clr não está sendo executado corretamente, talvez você queira habilitar o 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 encerrar antes da conclusão do seu código gerenciado em execução. Usando std::set_terminate e SIGTERM pode causar esse problema. See signal Constants and set_terminate (<exception>) for more information.

Usando os novos recursos do Visual C++

Após seu aplicativo compila, links e é executado, você pode começar a usar.NET recursos em qualquer módulo compilado com /clr. For more information, see Language Features for Targeting the CLR.

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 a conversão de Managed Extensions for C++, consulte C + + / CLI Primer de migração.

Para obter informações sobre.Consulte a programação NET no Visual C++:

Consulte também

Conceitos

Mistos de Assemblies (nativos e gerenciados)