Compartilhar via


Anatomia de um arquivo IDL

Esses arquivos IDL de exemplo demonstram as construções fundamentais da definição de interface. Alocação de memória, empacotamento personalizado e mensagens assíncronas são apenas alguns dos recursos que você pode implementar em uma interface COM personalizada. Os atributos MIDL são usados para definir interfaces COM. Para obter mais informações sobre como implementar interfaces e bibliotecas de tipos, incluindo um resumo dos atributos MIDL, consulte Definições de interface e bibliotecas de tipos no Guia e referência do programador MIDL. Para obter uma referência completa de todos os atributos, palavras-chave e diretivas MIDL, consulte a Referência de linguagem MIDL.

exemplo.idl

O arquivo IDL de exemplo a seguir define duas interfaces COM. A partir desse arquivo IDL, Midl.exe gerará arquivos de cabeçalho e código proxy/stub e marshaling. Uma dissecação linha por linha segue o exemplo.

//
// 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);
}; 
 

A instrução de importação IDL é usada aqui para trazer um arquivo de cabeçalho, Mydefs.h, que contém tipos definidos pelo usuário, e Unknwn.idl, que contém a definição de IUnknown, da qual IFace1 e IFace2 derivam.

O atributo object identifica a interface como uma interface de objeto e diz ao compilador MIDL para gerar código proxy/stub em vez de stubs de cliente e servidor RPC. Os métodos de interface de objeto devem ter um tipo de retorno de HRESULT, para permitir que o mecanismo RPC subjacente relate erros para chamadas que não são concluídas devido a problemas de rede.

O atributo uuid especifica o identificador de interface (IID). Cada interface, classe e biblioteca de tipos deve ser identificada com seu próprio identificador exclusivo. Use o utilitário Uuidgen.exe para gerar um conjunto de IDs exclusivos para suas interfaces e outros componentes.

A palavra-chave interface define o nome da interface. Todas as interfaces de objeto devem derivar, direta ou indiretamente, de IUnknown.

O parâmetro in direcional especifica um parâmetro que é definido somente pelo chamador. O parâmetro out especifica os dados que são passados de volta para o chamador. O uso de ambos os atributos direcionais em um parâmetro especifica que o parâmetro é usado tanto para enviar dados para o método quanto para passar dados de volta para o chamador.

O atributo pointer_default especifica o tipo de ponteiro padrão (exclusivo, ref ou ptr) para todos os ponteiros, exceto para aqueles incluídos em listas de parâmetros. Se nenhum tipo padrão for especificado, MIDL assumirá que ponteiros únicos são exclusivos. No entanto, quando você tiver vários níveis de ponteiros, deverá especificar explicitamente um tipo de ponteiro padrão, mesmo se desejar que o tipo padrão seja exclusivo.

No exemplo anterior, a matriz BkfstStuff[ ] é uma matriz conforme, cujo tamanho é determinado em tempo de execução. O atributo max_is especifica a variável que contém o valor máximo para o índice da matriz.

O atributo size_is também é usado para especificar o tamanho de uma matriz ou, como no exemplo anterior, vários níveis de ponteiros. No exemplo, a ligação pode ser feita sem saber com antecedência quantos dados serão retornados.

Exemplo2.idl

O exemplo IDL a seguir (que reutiliza as interfaces descritas no exemplo IDL anterior) mostra as várias maneiras de gerar informações de biblioteca de tipos para 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
 

O atributo helpstring é opcional, você o usa para descrever brevemente o objeto ou para fornecer uma linha de status. Essas cadeias de caracteres de ajuda são legíveis com um navegador de objetos, como o fornecido com o Microsoft Visual Basic.

O atributo dual no IFace3 cria uma interface que é uma interface de despacho e uma interface COM. Como ele é derivado de IDispatch, uma interface dupla oferece suporte a automação, que é o que o atributo oleautomation especifica. IFace3 importa Oaidl.idl para obter a definição de IDispatch.

A instrução library define a biblioteca de tipos ExampleLib, que tem seus próprios atributos uuid, helpstring e version.

Dentro da definição de biblioteca de tipos, a diretiva importlib traz uma biblioteca de tipos compilada. Todas as definições de biblioteca de tipos devem trazer a biblioteca de tipos base definida em Stdole32.tlb.

Essa definição de biblioteca de tipos demonstra três maneiras diferentes de incluir interfaces na biblioteca de tipos. IFace3 é incluído apenas referenciando-o dentro da instrução da biblioteca.

A instrução coclass define uma classe de componente totalmente nova, BkfstComponent, que inclui duas interfaces definidas anteriormente, IFace1 e IFace2. O atributo padrão designa IFace1 como a interface padrão.

IFace4 é descrito na instrução da biblioteca. O atributo propput em MethodD indica que o método executa uma ação definida em uma propriedade de mesmo nome. O atributo propget indica que o método recupera informações de uma propriedade de mesmo nome que o método. O atributo retval em MethodD designa um parâmetro de saída que contém o valor de retorno da função.