Diretiva #import (C++)

Específico do C++

Usada para incorporar informações de uma biblioteca de tipos. O conteúdo da biblioteca de tipos é convertido em classes do C++, a maioria descrevendo as interfaces COM.

Sintaxe

#import "filename" [attributes]
#import<filename> [attributes]

Parâmetros

filename
Especifica a biblioteca de tipos a ser importada. O nome do arquivo pode ser um dos seguintes tipos:

  • O nome de um arquivo que contém uma biblioteca de tipos, como um arquivo .olb, .tlb ou .dll. A palavra-chave file:, pode preceder cada nome de arquivo.

  • O progid de um controle na biblioteca de tipos. A palavra-chave progid:, pode preceder cada progid. Por exemplo:

    #import "progid:my.prog.id.1.5"
    

    Para obter mais informações sobre progids, consulte Especificando a ID de localização e o número de versão.

    Quando você usa um compilador cruzado de 32 bits em um sistema operacional de 64 bits, o compilador só pode ler o hive do registro de 32 bits. Pode ser conveniente usar o compilador de 64 bits nativo para criar e registrar uma biblioteca de tipos de 64 bits.

  • A ID da biblioteca de tipos. A palavra-chave libid:: pode preceder cada ID de biblioteca. Por exemplo:

    #import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
    

    Se você não especificar version ou lcid, as regras aplicadas a progid: também serão aplicadas a libid:.

  • Um arquivo executável (.exe).

  • Um arquivo de biblioteca (.dll) que contém um recurso de biblioteca de tipos (como um .ocx).

  • Um documento composto que contém uma biblioteca de tipos.

  • Qualquer outro formato de arquivo que possa ser compreendido pela API LoadTypeLib.

atributos
Um ou mais atributos de #import. Separe os atributos com espaços ou vírgulas. Por exemplo:

#import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only

-ou-

#import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only

Comentários

Ordem de pesquisa para filename

filename é opcionalmente precedido por uma especificação de diretório. O nome do arquivo deve nomear um arquivo existente. A diferença entre os dois formatos de sintaxe é a ordem em que o pré-processador procura os arquivos de biblioteca de tipos quando o caminho é especificado de forma incompleta.

Formato de sintaxe Ação
Forma entre aspas Instrui o pré-processador a procurar arquivos de biblioteca de tipos primeiro no diretório do arquivo que contém a instrução #import e depois nos diretórios dos arquivos que incluam (#include) esse arquivo. Em seguida, o pré-processador pesquisa ao longo dos caminhos mostrados abaixo.
Forma de colchete angular Instrui o pré-processador a procurar arquivos de biblioteca de tipos ao longo dos seguintes caminhos:

1. A lista de caminhos da variável de ambiente PATH
2. A lista de caminhos da variável de ambiente LIB
3. O caminho especificado pela opção de compilador /I, exceto que o compilador está procurando por uma biblioteca de tipos que foi referenciada em outra biblioteca de tipos com o atributo no_registry.

Especificar a ID de localização e o número de versão

Ao especificar um progid, você também pode especificar a ID de localização e o número de versão do progid. Por exemplo:

#import "progid:my.prog.id" lcid("0") version("4.0)

Se você não especificar uma ID de localização, um progid será escolhido de acordo com as seguintes regras:

  • Se houver apenas uma ID de localização, essa será usada.

  • Se houver mais de uma ID de localização, será usada a primeira delas com número de versão 0, 9 ou 409.

  • Se houver mais de uma ID de localização e nenhuma delas for 0, 9 ou 409, será usada a última.

  • Se você não especificar um número de versão, será usada a versão mais recente.

Arquivos de cabeçalho criados por importação

#import cria dois arquivos de cabeçalho que reconstroem o conteúdo da biblioteca de tipos no código-fonte do C++. O arquivo de cabeçalho principal é semelhante àquele produzido pelo compilador de MIDL (linguagem IDL da Microsoft), mas com código gerado pelo compilador e dados adicionais. O arquivo de cabeçalho principal tem o mesmo nome base que a biblioteca de tipos, mais a extensão .TLH. O arquivo de cabeçalho secundário tem o mesmo nome base que a biblioteca de tipos, com a extensão .TLI. Ele contém as implementações para funções de membro geradas pelo compilador e está incluído (#include) no arquivo de cabeçalho principal.

Se estiver importando uma propriedade dispinterface que usa parâmetros byref, #import não gera uma instrução __declspec(property) para a função.

Os dois arquivos de cabeçalho são colocados no diretório de saída especificado pela opção /Fo (nomear arquivo de objeto). Em seguida, eles são lidos e compilados pelo compilador como se o arquivo de cabeçalho principal tivesse sido nomeado por uma diretiva #include.

As seguintes otimizações de compilador vêm com a diretiva #import:

  • O arquivo de cabeçalho, quando é criado, recebe o mesmo carimbo de data/hora que a biblioteca de tipos.

  • Quando #import é processada, o compilador verifica primeiro se o cabeçalho existe e está atualizado. Em caso positivo, ele não precisa ser recriado.

A diretiva #import também participa da recompilação mínima e pode ser colocada em um arquivo de cabeçalho pré-compilado. Para obter mais informações, consulte Criar arquivos de cabeçalho pré-compilados.

Arquivo de cabeçalho principal da biblioteca de tipos

O arquivo de cabeçalho principal da biblioteca de tipos consiste em sete seções:

  • Texto clichê de título: inclui comentários, a instrução #include para COMDEF.H (que define algumas macros padrão usadas no cabeçalho) e outras informações de configuração.

  • Referências de encaminhamento e typedefs: consiste em declarações de estrutura como struct IMyInterface e typedefs.

  • Declarações de ponteiro inteligente: a classe de modelo _com_ptr_t é um ponteiro inteligente. Ela encapsula ponteiros de interface e elimina a necessidade de chamar funções AddRef, Release e QueryInterface. Ela também oculta a chamada CoCreateInstance ao criar um novo objeto COM. Esta seção usa a instrução de macro _COM_SMARTPTR_TYPEDEF para estabelecer typedefs de interfaces COM como especializações modelo da classe de modelo _com_ptr_t. Por exemplo, para a interface IMyInterface, o arquivo .TLH contém:

    _COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));
    

    que o compilador expande para:

    typedef _com_ptr_t<_com_IIID<IMyInterface, __uuidof(IMyInterface)> > IMyInterfacePtr;
    

    O tipo IMyInterfacePtr pode então ser usado no lugar do ponteiro de interface bruto IMyInterface*. Consequentemente, não há necessidade de chamar as várias funções de membro IUnknown

  • Declarações de typeinfo: consiste basicamente em definições de classe e outros itens que expõem os itens individuais de typeinfo retornados por ITypeLib:GetTypeInfo. Nesta seção, cada typeinfo da biblioteca de tipos é refletido no cabeçalho em um formato que depende das informações de TYPEKIND.

  • Definição de GUID de estilo antigo opcional: contém inicializações das constantes de GUID nomeadas. Esses nomes têm o formulário CLSID_CoClass e IID_Interface, similares àqueles gerados pelo compilador de MIDL.

  • Instrução #include para o cabeçalho secundário da biblioteca de tipos.

  • Texto clichê de rodapé: atualmente, inclui #pragma pack(pop).

Todas as seções, exceto a seção de texto clichê de título e de texto clichê de rodapé, são colocadas em um namespace cujo nome é especificado pela instrução library no arquivo IDL original. Você pode usar os nomes do cabeçalho de biblioteca de tipos por meio de uma qualificação explícita usando o nome do namespace. Ou você pode incluir a seguinte instrução:

using namespace MyLib;

imediatamente depois da instrução #import no código-fonte.

O namespace pode ser suprimido ao usar o atributo no_namespace) da diretiva #import. No entanto, suprimir o namespace pode resultar em colisões de nomes. O namespace também pode ser renomeado pelo atributo rename_namespace.

O compilador fornece o caminho completo para toda dependência da biblioteca de tipos exigida pela biblioteca que esteja em processamento. O caminho é escrito, na forma de comentários, no cabeçalho da biblioteca de tipos (.TLH) gerado pelo compilador para cada biblioteca de tipos processada.

Se uma biblioteca de tipos incluir referências a tipos definidos em outras bibliotecas, o arquivo .TLH incluirá comentários do seguinte tipo:

//
// Cross-referenced type libraries:
//
//  #import "c:\path\typelib0.tlb"
//

O nome de arquivo real no comentário #import é o caminho completo da biblioteca de tipos de referência cruzada, conforme armazenado no registro. Se você encontrar erros causados pela ausência de definições de tipo, verifique os comentários no cabeçalho do .TLH para saber quais bibliotecas de tipos dependentes precisarão ser importadas primeiro. Erros prováveis são erros de sintaxe (por exemplo, C2143, C2146, C2321), C2501 (especificadores de declarações ausentes) ou C2433 ("embutido" não permitido na declaração de dados) ao compilar o arquivo .TLI.

Para resolver erros de dependência, determine quais dos comentários de dependência não são fornecidos de outra forma por cabeçalhos do sistema e então forneça uma diretiva #import em algum momento antes da diretiva #import da biblioteca de tipos dependente.

Atributos de #import

#import pode incluir opcionalmente um ou mais atributos. Esses atributos instruem o compilador a modificar o conteúdo dos cabeçalhos de biblioteca de tipos. Um símbolo de barra invertida (\) pode ser usado para incluir linhas adicionais em uma única instrução #import. Por exemplo:

#import "test.lib" no_namespace \
   rename("OldName", "NewName")

Para obter mais informações, confira Atributos de #import.

END C++ Específico

Confira também

Diretivas de pré-processador
Suporte a COM do compilador