Partilhar via


Como migrar para /clr

Este tópico aborda problemas que ocorrem ao compilar o código nativo com /clr (consulte /clr (compilação do Common Language Runtime) para obter mais informações). /clr permite que os módulos do Visual C++ têm permissão para invocar e sejam invocados os assemblies do .NET para manter a compatibilidade com módulos não gerenciado. Consulte Assemblies mistos (nativos e gerenciados) e Nativo e interoperabilidade .NET para obter mais informações sobre as vantagens de compilação com /clr.

Problemas conhecidos que criam projetos de biblioteca com /clr

Visual Studio contém alguns problemas conhecidos ao criar a biblioteca projetos com /clr:

  • O código pode tipos de consulta em tempo de execução com CRuntimeClass::FromName. No entanto, se um tipo está em um MSIL (.dll compilado com /clr), a chamada para CRuntimeClass::FromName pode falhar se ocorrer antes da execução estático dos construtores no .dll gerenciado (não verá esse problema se a chamada de FromName acontece depois que o código gerenciado executado no .dll). Para resolver esse problema, você pode forçar a construção do construtor estático gerenciado definindo uma função no .dll gerenciado, exportando e, ao invocar a do aplicativo MFC nativos. Por exemplo:

    // Extension DLL Header file:
    __declspec( dllexport ) void EnsureManagedInitialization () {
       // managed code that won't be optimized away
       System::GC::KeepAlive(System::Int32::MaxValue);
    }
    

Compile com o Visual C++

Antes de usar /clr em qualquer módulo em seu projeto, primeiro crie e vincular seu projeto nativo com o Visual Studio 2010.

As etapas a seguir, seguidas em ordem, forneça o caminho o mais fácil a uma compilação de /clr . É importante criar e executar o projeto depois de cada uma dessas etapas.

Versões anteriores do Visual C++ 2003

Se você estiver atualizando do Visual Studio 2010 de uma versão anterior do Visual C++ 2003, você pode ver os erros do compilador relacionados à conformidade padrão do C++ aprimorado no Visual C++ 2003

Atualização do Visual C++ 2003

Prévio de projetos com Visual C++ 2003 também deve primeiro ser compilado sem /clr porque o Visual Studio tem gerado agora a conformidade de ANSI/ISO e as algumas alterações. É provável que a alteração exigir a maioria de atenção é Recursos de segurança no CRT. O código que usa o CRT muito provavelmente gerar avisos de substituição. Esses avisos podem ser suprimidos, mas migrar a nova Versões aprimoradas de segurança de funções CRT é preferencial, porque proporcionam melhor segurança e podem revelar problemas de segurança em seu código.

Atualização das extensões gerenciadas para C++

Os projetos criados com o Visual C++ .NET ou o Visual C++ 2003 que usaram extensões gerenciadas para C++ exigirão pelo menos uma alteração nas configurações de projeto, como essas extensões são substituídas agora. No, o código escrito com extensões gerenciadas para C++ não criará em /clr. Use /clr:oldSyntax em vez disso.

Código C de converter em C++

Embora o Visual Studio cria arquivos de 2.0 C, é necessário convertê-los a C++ para uma compilação de /clr . O nome de arquivo atual não tem que ser alterado; você pode usar /Tp (consulte) /Tc, /Tp, /TC, /TP (especificar tipo de arquivo de origem). Observe que embora os arquivos de código-fonte C++ sejam necessários para /clr, não é necessário fator novamente seu código para usar paradigmas orientados a objeto.

Código C é muito provável exigir alterações quando criado porque arquivo c. criando As regras de classificação segurança C++ são restritas, de modo que as conversões de tipos devem ser feitas com conversões explícitas. Por exemplo, o malloc retorna um ponteiro nulo, mas pode ser atribuído a um ponteiro para um determinado tipo em C com uma conversão:

int* a = malloc(sizeof(int));   // C code
int* b = (int*)malloc(sizeof(int));   // C++ equivalent

Os ponteiros de função também são estritamente tipo seguro em C++, assim que o seguinte código C requer a alteração. Em C++ é melhor criar typedef que define o tipo de ponteiro de função, e depois usar esse tipo para converter ponteiros da função:

NewFunc1 = GetProcAddress( hLib, "Func1" );   // C code
typedef int(*MYPROC)(int);   // C++ equivalent
NewFunc2 = (MYPROC)GetProcAddress( hLib, "Func2" );

C++ também requer que as funções são definidas ou protótipos completo antes que possam ser referenciadas ou invocado.

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

Finalmente, enquanto que as chamadas do COM o estilo 2.0 - c requerem o uso explícito de v- tabela e do ponteiro de this , C++ não tem:

COMObj1->lpVtbl->Method(COMObj, args);  // C code
COMObj2->Method(args);  // C++ equivalent

Reconfigurar configurações de projeto

Após seu projeto do cria e executa no Visual Studio 2010 que você deve criar novas configurações de projeto para /clr em vez de alterar as configurações padrão. /clr é incompatível com algumas opções do compilador e criar configurações separadas permite a você criar seu projeto como o modo nativo ou gerenciado. Quando /clr é selecionado nas páginas de propriedades caixa de diálogo, as configurações do projeto não compatíveis com /clr são desabilitadas (e as opções desabilitadas não são restauradas automaticamente se /clr é cancelado a seleção subsequentemente).

Crie novas configurações de projeto

Você pode usar a opção de Copiar configurações de em Caixa de diálogo de configuração do novo projeto criar uma configuração de projeto com base nas configurações existentes do projeto. Faça isto uma vez para a configuração de depuração e outra para a instalação da versão. As alterações subsequentes podem ser aplicadas às configurações específico de /clr , deixando apenas as configurações originais do projeto intactos.

Os projetos que usam regras personalizadas da construção podem exigir a atenção adicional.

Esta etapa tem implicações diferentes para projetos que usam makefiles. Nesse caso construção- um destino separado pode ser configurado, ou o específico da versão da compilação de /clr pode ser criada de uma cópia original.

Configurações de projeto de alteração

/clr pode ser selecionado no ambiente de desenvolvimento seguindo as instruções em /clr (compilação do Common Language Runtime). Conforme mencionado anteriormente, essa etapa desabilitará automaticamente conflitantes configurações de projeto.

Dica

Ao atualizar um projeto gerenciado de biblioteca ou do serviço Web do Visual C++ 2003, a opção de compilador de /Zl adicionado a Linha de Comando a página de propriedades.Isso fará LNK2001.Remover /Zl da página de propriedades de Linha de Comando a ser resolvido.Consulte /Zl (omitir nome da biblioteca padrão) e Como abrir páginas de propriedade do projeto para obter mais informações.Ou, adicione msvcrt.lib e msvcmrt.lib à propriedade de Dependências Adicionais do vinculador.

Para projetos desenvolvidos com makefiles, as opções do compilador incompatíveis devem ser desabilitadas manualmente uma vez que /clr é adicionado. Consulte//clr Restrições para obter informações sobre as opções do compilador que não são compatíveis com /clr.

Cabeçalhos pré-compilados

Os cabeçalhos pré-compilados têm suporte em /clr. No entanto, se você criar apenas alguns de seus arquivos de CPP com /clr (que cria o restante como o nativo) algumas alterações serão necessárias como os cabeçalhos pré-compilados gerados com /clr não são compatíveis com os gerados sem /clr. Essa incompatibilidade ocorre devido ao fato de que /clr gerencia e exige metadados. /clr compilado os módulos em virtude disso pode não os cabeçalhos pré-compilados de uso que não contêm metadados, e não os módulos de /clr não podem usar os arquivos de cabeçalho pré-compilados que contêm a meta - dados.

A maneira mais fácil de criar um projeto onde alguns módulos sejam /clr compilado é desabilitar completamente cabeçalhos pré-compilados. (Na caixa de diálogo páginas de propriedades do projeto, abra o nó C/C++, selecione e cabeçalhos pré-compilados. Altere a propriedade pré-compilada de cabeçalhos de criação/use “que não usa cabeçalhos pré-compilados”).

No entanto, particularmente para grandes projetos, os cabeçalhos pré-compilados fornecem muito melhor a velocidade da compilação, portanto desabilitar esse recurso não é desejável. Nesse caso é melhor configurar /clr e arquivos de /clr não usar cabeçalhos pré-compilados separados. Isso pode ser feito em uma etapa várias selecionando os módulos para ser /clr criado usando Solution Explorer, clique com o botão direito do mouse no grupo, e selecionando propriedades. Altere o para criar/uso PCH por meio de Arquivo e propriedades do Arquivo de cabeçalho pré-compilados usar um nome de arquivo diferente do cabeçalho e o arquivo de PCH respectivamente.

Erros de composição

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

Mesclagem de metadados

As versões diferentes dos tipos de dados podem fazer com que o vinculador falhar porque os metadados gerados para os dois tipos de não corresponderem. (Isso ocorre normalmente quando os membros de um tipo estejam definidos condicional, mas as condições não são as mesmas para todos os arquivos de CPP que usam o tipo.) Nesse caso, o vinculador falha de relatório somente o nome de símbolo e o nome do segundo arquivo de OBJ onde o tipo foi definido. Geralmente é útil ativar ou desativar a ordem em que os arquivos de OBJ serão enviados ao vinculador para descobrir o local da outra versão do tipo de dados.

Deadlock de bloqueios de carregador

No Visual C++ .NET e Visual C++ 2003, a inicialização em /clr não existe deadlock não determinística. Esse problema é conhecido como “o deadlock de bloqueio carregador”. No Visual Studio 2010, esse deadlock é mais fácil de evitar, é detectado e relatado em tempo de execução, e não é mais não determinística. Encontre o problema de bloqueio de carregador ainda é possível, mas agora é muito mais fácil evitar e corrigir. Consulte para Inicialização de assemblies mistos plano de fundo, orientação, e soluções detalhados.

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 é garantia de ser inicializada até que uma parte gerenciada da DLL seja executada. Metadados de referência com Diretiva #using (C++).

Visibilidade do tipo

Os tipos nativos agora são privativos por padrão. No Visual C++ .NET 2002 e no Visual C++ 2003, os tipos nativos foram públicos por padrão. Isso pode resultar em um tipo nativo que não é visível fora da DLL. Resolver este erro public adicionando a esses tipos. Consulte Tipo e a visibilidade de membro para maiores informações.

Problemas de ponto flutuante e alinhamento

__controlfp não tem suporte em Common Language Runtime (consulte _control87, _controlfp, __control87_2 para obter mais informações). CLR também não respeitará align (C++).

Inicialização da

Common Language Runtime inicializa COM automaticamente quando um módulo é inicializada (quando COM ele é iniciado automaticamente fez de modo a MTA). No resultado, explicitamente inicializar COM gerencie os códigos de retorno que indica que a já está inicializado. Tentar inicializar COM explicitamente com um modelo de threading CLR quando já inicializou COM a outro modelo de threading pode causar o aplicativo falhar.

Inicia COM de Common Language Runtime como a MTA por padrão; use /CLRTHREADATTRIBUTE (definir atributo de thread CLR) para alterar isso.

Problemas de desempenho

Você pode ver desempenho reduzido quando os métodos C++ nativos gerados a MSIL são chamados indiretamente (chamadas de função virtuais ou o uso de ponteiros de função). Para saber mais sobre isso, consulte Conversão dupla (C++).

Ao mover da MSIL nativo, você observará um aumento no tamanho do conjunto de trabalho. Isso é porque Common Language Runtime fornece muitos recursos para garantir que os programas executados corretamente. Se seu aplicativo de /clr não está sendo executado corretamente, você pode habilitar C4793 (desativado por padrão), consulta Aviso do compilador (nível 1 e 3) C4793 para obter mais informações.

O programa falha no desligamento

Em alguns casos, CLR pode desconectar antes de executar o código gerenciado está concluído. Usar std::set_terminate e SIGTERM pode causar isso. Consulte Constantes de sinal e set_terminate (<exception>) para obter mais informações.

Usando novos recursos do Visual C++

Depois que seu aplicativo compila, vincula, e é executado, você pode começar a usar os recursos do .NET em qualquer módulo compilado com /clr. Para obter mais informações, consulte Extensões de componente para plataformas de tempo de execução.

Se você usou extensões gerenciadas para C++, você pode converter seu código para usar a nova sintaxe. Para obter um resumo das diferenças sintáticas, consulte Managed Extensions for C++ Syntax Upgrade Checklist. Para obter detalhes da conversão de extensões gerenciadas para C++, consulte Primer de migração C++/CLI.

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

Consulte também

Conceitos

Assemblies mistos (nativos e gerenciados)