Directiva #import (C++)
Específico de C++
Se utiliza para incorporar información de una biblioteca de tipos. El contenido de la biblioteca de tipos se convierte en clases de C++, que describen fundamentalmente las interfaces COM.
Sintaxis
#import "filename" [attributes]
#import<filename> [attributes]
Parámetros
nombredearchivo
Especifica la biblioteca de tipos que se va a importar. filename puede ser uno de los siguientes tipos:
El nombre de un archivo que contiene una biblioteca de tipos, como un archivo .olb, .tlb o .dll. La palabra clave,
file:
, puede preceder a cada nombre de archivo.El identificador de programa de un control en la biblioteca de tipos. La palabra clave,
progid:
, puede preceder a cada progid. Por ejemplo:#import "progid:my.prog.id.1.5"
Para obtener más información sobre los progids, vea Especificación del id. y el número de versión de localización.
Cuando se usa un compilador cruzado de 32 bits en un sistema operativo de 64 bits, el compilador solo puede leer el subárbol del registro de 32 bits. Es posible que desee utilizar el compilador de 64 bits nativo para compilar y registrar una biblioteca de tipos de 64 bits.
El identificador de biblioteca de la biblioteca de tipos. La palabra clave,
libid:
, puede preceder a cada id. de biblioteca. Por ejemplo:#import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
Si no especifica
version
olcid
, las reglas que se aplican aprogid:
también se aplican alibid:
.Un archivo ejecutable (.exe).
Un archivo de biblioteca (.dll) que contiene un recurso de biblioteca de tipos (como un archivo .ocx).
Un documento compuesto que contiene una biblioteca de tipos.
Cualquier otro formato de archivo que API LoadTypeLib pueda comprender.
attributes
Uno o varios atributos #import. Separa los atributos con un espacio en blanco o con una coma. Por ejemplo:
#import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only
O bien
#import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only
Comentarios
Orden de búsqueda de nombre de archivo
filename va precedido opcionalmente por una especificación de directorio. El nombre de archivo debe designar un archivo existente. La diferencia entre las dos formas de sintaxis es el orden en que el preprocesador busca los archivos de biblioteca de tipos cuando no se especifica completamente la ruta de acceso.
Forma de sintaxis | Action |
---|---|
Formato con comillas | Indica al preprocesador que busque archivos de biblioteca de tipos primero en el directorio del archivo que contiene la instrucción #import y, después, en los directorios de los archivos que incluyen (#include ) ese archivo. A continuación, el preprocesador busca en las rutas de acceso que se muestran a continuación. |
Formato con corchetes angulares | Indica al preprocesador que busque archivos de biblioteca de tipos en las siguientes rutas de acceso: 1. La lista de rutas de acceso de la variable de entorno PATH .2. La lista de rutas de acceso de la variable de entorno LIB .3. La ruta de acceso que especifica la opción de compilador /I, excepto si el compilador busca una biblioteca de tipos a la que se hizo referencia desde otra biblioteca de tipos con el atributo no_registry. |
Especificación del id. de localización y el número de versión
Cuando especifica un identificador de programa, también puede especificar el identificador y el número de versión de localización del identificador de programa. Por ejemplo:
#import "progid:my.prog.id" lcid("0") version("4.0)
Si no especifica un id. de localización, se elige un progid de acuerdo con las reglas siguientes:
Si solo hay un id. de localización, es el que se utiliza.
Si hay más de un id. de localización, se usa el primero con el número de versión 0, 9 o 409.
Si hay más de un id. de localización y ninguno de ellos es 0, 9 o 409, se utiliza el último.
Si no especifica un número de versión, se utiliza la versión más reciente.
Archivos de encabezado que crea la directiva de importación
#import crea dos archivos de encabezado que reconstruyen el contenido de la biblioteca de tipos en código fuente de C++. El archivo de encabezado principal es similar al que genera el compilador de Lenguaje de definición de interfaz de Microsoft (MIDL), pero con código y datos adicionales generados por el compilador. El archivo de encabezado principal tiene el mismo nombre base que la biblioteca de tipos, más una extensión .TLH. El archivo de encabezado secundario tiene el mismo nombre base que la biblioteca de tipos, con una extensión .TLI. Contiene implementaciones para funciones miembro generadas por el compilador y se incluye (#include
) en el archivo de encabezado principal.
Si se importa una propiedad dispinterface que utilice parámetros byref
, #import no generará la instrucción __declspec(property) para la función.
Ambos archivos de encabezado se colocan en el directorio de resultados que especifica la opción /Fo (asignar nombre al archivo objeto). Después, el compilador los lee y compila como si una directiva #include
denominase el archivo de encabezado principal.
Las optimizaciones del compilador siguientes se incluyen en la directiva #import:
El archivo de encabezado, cuando se crea, tiene la misma marca de tiempo que la biblioteca de tipos.
Cuando se procesa #import, el compilador comprueba primero si el encabezado existe y si está actualizado. En caso afirmativo, no necesita volver a crearlo.
La directiva #import también participa en la recompilación mínima y puede colocarse en un archivo de encabezado precompilado. Para obtener más información, vea Creación de archivos de encabezado precompilados.
Archivo de encabezado principal de la biblioteca de tipos
El archivo de encabezado principal de la biblioteca de tipos se compone de siete secciones:
Encabezado reutilizable: consta de los comentarios, la instrucción
#include
para COMDEF.H (que define algunas macros estándar utilizadas en el encabezado) y otro tipo de información de instalación.Definiciones de tipo y referencias adelantadas: consta de declaraciones de estructura como
struct IMyInterface
y definiciones de tipo.Declaraciones de puntero inteligente: la clase de plantilla
_com_ptr_t
es un puntero inteligente. Encapsula punteros de interfaz y elimina la necesidad de llamar a las funcionesAddRef
,Release
yQueryInterface
. También oculta la llamada aCoCreateInstance
al crear un objeto COM. En esta sección se usa la instrucción de macro_COM_SMARTPTR_TYPEDEF
para establecer definiciones de tipo de interfaces COM como especializaciones de plantilla de la clase de plantilla _com_ptr_t. Por ejemplo, para la interfazIMyInterface
, el archivo .TLH contendrá lo siguiente:_COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));
que el compilador expandirá a:
typedef _com_ptr_t<_com_IIID<IMyInterface, __uuidof(IMyInterface)> > IMyInterfacePtr;
El tipo
IMyInterfacePtr
se puede utilizar a continuación en lugar del puntero de interfaz sin formatoIMyInterface*
. Por lo tanto, no es necesario llamar a las distintas funciones miembroIUnknown
.Declaraciones de typeinfo: principalmente consta de definiciones de clase y otros elementos que exponen los elementos individuales de typeinfo que devuelve
ITypeLib:GetTypeInfo
. En esta sección, cada typeinfo de la biblioteca de tipos se refleja en el encabezado de forma dependiente de la información deTYPEKIND
.Definición de GUID de estilo anterior opcional: contiene inicializaciones de las constantes de GUID con nombre. Estos nombres tienen el formato
CLSID_CoClass
yIID_Interface
, similares a los que genera el compilador MIDL.Instrucción
#include
para el encabezado secundario de la biblioteca de tipos.Sección del pie de página reutilizable: actualmente incluye
#pragma pack(pop)
.
Todas las secciones, excepto la sección del encabezado reutilizable y del pie de página reutilizable, se incluyen en un espacio de nombres con el nombre que especifica la instrucción library
en el archivo IDL original. Puede usar los nombres del encabezado de la biblioteca de tipos mediante una calificación explícita con el nombre del espacio de nombres. O bien puede incluir la instrucción siguiente:
using namespace MyLib;
inmediatamente después de la instrucción #import en el código fuente.
El espacio de nombres se puede suprimir mediante el atributo no_namespace de la directiva #import. Sin embargo, la supresión del espacio de nombres puede dar lugar a conflictos de nombres. También se puede cambiar el nombre del espacio de nombres mediante el atributo rename_namespace.
El compilador proporciona la ruta de acceso completa a cualquier dependencia de la biblioteca de tipos necesaria para la biblioteca de tipos que está actualmente en procesamiento. La ruta de acceso se escribe, en forma de comentarios, en el encabezado de la biblioteca de tipos (.TLH) que el compilador genera para cada biblioteca de tipos procesada.
Si una biblioteca de tipos contiene referencias a tipos definidos en otras bibliotecas de tipos, el archivo .TLH incluirá comentarios del siguiente tipo:
//
// Cross-referenced type libraries:
//
// #import "c:\path\typelib0.tlb"
//
El nombre de archivo real en el comentario de #import es la ruta de acceso completa de la biblioteca de tipos a la que se hace referencia cruzada, tal como se almacena en el registro. Si detecta errores que provocados por la falta de definiciones de tipo, compruebe los comentarios en el encabezado del archivo .TLH para ver qué bibliotecas de tipos dependientes han de importarse primero. Los errores probables son errores de sintaxis (por ejemplo, C2143, C2146, C2321), C2501 (faltan especificadores decl) o C2433 (“inline” no permitida en la declaración de datos) mientras se compila el archivo .TLI.
Para resolver los errores de dependencia, debe determinar los comentarios de dependencia que, de otro modo, los encabezados de sistema no proporcionarían, e indicar una directiva #import en algún momento antes de la directiva #import de la biblioteca de tipos dependiente.
atributos #import
#import puede incluir opcionalmente uno o varios atributos. Estos atributos indican al compilador que modifique el contenido de los encabezados de la biblioteca de tipos. Se puede utilizar un símbolo de barra diagonal inversa (\) para incluir líneas adicionales en una única instrucción #import. Por ejemplo:
#import "test.lib" no_namespace \
rename("OldName", "NewName")
Para obtener más información, vea Atributos #import.
END C++ específico
Consulte también
Directivas de preprocesador
Compatibilidad con COM del compilador