Compartir a través de


Anatomía de un archivo IDL

Estos archivos IDL de ejemplo muestran las construcciones fundamentales de la definición de interfaz. La asignación de memoria, la serialización personalizada y la mensajería asincrónica son solo algunas de las características que puede implementar en una interfaz COM personalizada. Los atributos MIDL se usan para definir interfaces COM. Para obtener más información sobre cómo implementar interfaces y bibliotecas de tipos, incluido un resumen de los atributos MIDL, vea Definiciones de interfaz y bibliotecas de tipos en la Guía y referencia del programador de MIDL. Para obtener una referencia completa de todos los atributos, palabras clave y directivas MIDL, consulte la Referencia del lenguaje MIDL.

Example.idl

En el siguiente archivo IDL de ejemplo se definen dos interfaces COM. A partir de este archivo IDL, Midl.exe generará archivos de encabezado y código proxy/código auxiliar y serialización. Una disección de línea a línea sigue el ejemplo.

//
// Example.idl 
//
import "mydefs.h","unknwn.idl"; 
[
object,
uuid(a03d1420-b1ec-11d0-8c3a-00c04fc31d2f),
] interface IFace1 : IUnknown
{
HRESULT MethodA([in] short Bread, [out] BKFST * pBToast);
HRESULT MethodB([in, out] BKFST * pBPoptart);
};
 
[
object,
uuid(a03d1421-b1ec-11d0-8c3a-00c04fc31d2f),
pointer_default(unique)
] interface IFace2 : IUnknown
{
HRESULT MethodC([in] long Max,
                [in, max_is(Max)] BkfstStuff[ ],
                [out] long * pSize,
                [out, size_is( , *pSize)] BKFST ** ppBKFST);
}; 
 

La instrucción idl import se usa aquí para incluir un archivo de encabezado, Mydefs.h, que contiene tipos definidos por el usuario y Unknwn.idl, que contiene la definición de IUnknown, de la que se deriva IFace1 e IFace2.

El atributo object identifica la interfaz como una interfaz de objeto e indica al compilador MIDL que genere código proxy/stub en lugar de código auxiliar de servidor y cliente RPC. Los métodos de interfaz de objeto deben tener un tipo de valor devuelto HRESULT, para permitir que el mecanismo RPC subyacente notifique errores para las llamadas que no se completan debido a problemas de red.

El atributo uuid especifica el identificador de interfaz (IID). Cada interfaz, clase y biblioteca de tipos debe identificarse con su propio identificador único. Use la utilidad Uuidgen.exe para generar un conjunto de identificadores únicos para las interfaces y otros componentes.

La palabra clave interface define el nombre de la interfaz. Todas las interfaces de objeto deben derivar, directa o indirectamente, de IUnknown.

El parámetro in directional especifica un parámetro que solo establece el autor de la llamada. El parámetro out especifica los datos que se devuelven al autor de la llamada. El uso de ambos atributos direccionales en un parámetro especifica que el parámetro se usa tanto para enviar datos al método como para devolver los datos al autor de la llamada.

El atributo pointer_default especifica el tipo de puntero predeterminado (único, ref o ptr) para todos los punteros excepto los incluidos en las listas de parámetros. Si no se especifica ningún tipo predeterminado, MIDL supone que los punteros únicos son únicos. Sin embargo, cuando tenga varios niveles de punteros, debe especificar explícitamente un tipo de puntero predeterminado, incluso si desea que el tipo predeterminado sea único.

En el ejemplo anterior, la matriz BkfstStuff[ ] es una matriz conforme, cuyo tamaño se determina en tiempo de ejecución. El atributo max_is especifica la variable que contiene el valor máximo del índice de matriz.

El atributo size_is también se usa para especificar el tamaño de una matriz o, como en el ejemplo anterior, varios niveles de punteros. En el ejemplo, la llamada se puede realizar sin saber con antelación cuántas datos se devolverán.

Ejemplo2.idl

En el siguiente ejemplo de IDL (que reutiliza las interfaces descritas en el ejemplo anterior de IDL) se muestran las distintas formas de generar información de la biblioteca de tipos para las interfaces.

//
// Example2.idl
//

import "example.idl","oaidl.idl"; 

[
uuid(a03d1422-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace3 interface"),
pointer_default(unique);
dual,
oleautomation
] 
interface IFace3 : IDispatch
{
   HRESULT MethodD([in] BSTR OrderIn,
                   [out, retval] * pTakeOut);
}; //end IFace3 def

[
uuid(a03d1423-b1ec-11d0-8c3a-00c04fc31d2f),
version(1.0),
helpstring("Example Type Library"),
] library ExampleLib
{
  importlib("stdole32.tlb");
  interface IFace3;
  [
  uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
  helpstring("Breakfast Component Class")
  ] coclass BkfstComponent
    {
    [default]interface IFace1;
    interfaceIFace2
    }; //end coclass def

[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace4 interface"),
pointer_default(unique);
dual,
oleautomation
] 
interface IFace4 : IDispatch
{
[propput] HRESULT MethodD([in] BSTR OrderIn);
[propget] HRESULT MethodE([out, retval] * pTakeOut);
}; //end IFace4 def
 
}; //end library def
 

El atributo helpstring es opcional; se usa para describir brevemente el objeto o para proporcionar una línea de estado. Estas cadenas de ayuda son legibles con un explorador de objetos, como el proporcionado con Microsoft Visual Basic.

El atributo dual en IFace3 crea una interfaz que es una interfaz de distribución y una interfaz COM. Dado que se deriva de IDispatch, una interfaz dual admite Automation, que es lo que especifica el atributo oleautomation . IFace3 importa Oaidl.idl para obtener la definición de IDispatch.

La instrucción library define la biblioteca de tipos ExampleLib, que tiene sus propios atributos uuid, helpstring y version .

Dentro de la definición de la biblioteca de tipos, la directiva importlib incluye una biblioteca de tipos compilada. Todas las definiciones de biblioteca de tipos deben incluir la biblioteca de tipos base definida en Stdole32.tlb.

Esta definición de biblioteca de tipos muestra tres maneras diferentes de incluir interfaces en la biblioteca de tipos. IFace3 se incluye simplemente haciendo referencia a él dentro de la instrucción library.

La instrucción coclass define una clase de componente completamente nueva, BkfstComponent, que incluye dos interfaces definidas anteriormente, IFace1 e IFace2. El atributo predeterminado designa IFace1 como interfaz predeterminada.

IFace4 se describe en la instrucción library. El atributo propput de MethodD indica que el método realiza una acción establecida en una propiedad del mismo nombre. El atributo propget indica que el método recupera información de una propiedad del mismo nombre que el método . El atributo retval de MethodD designa un parámetro de salida que contiene el valor devuelto de la función.