Condividi tramite


Anatomia di un file IDL

Questi file IDL di esempio illustrano i costrutti fondamentali della definizione dell'interfaccia. L'allocazione di memoria, il marshalling personalizzato e la messaggistica asincrona sono solo alcune delle funzionalità che è possibile implementare in un'interfaccia COM personalizzata. Gli attributi MIDL vengono usati per definire le interfacce COM. Per altre informazioni sull'implementazione di interfacce e librerie dei tipi, incluso un riepilogo degli attributi MIDL, vedere Interface Definitions and Type Libraries (Definizioni di interfaccia e librerie dei tipi ) nella Guida e informazioni di riferimento per programmatori MIDL. Per un riferimento completo di tutti gli attributi, le parole chiave e le direttive MIDL, vedere le informazioni di riferimento sul linguaggio MIDL.

Example.idl

Il file IDL di esempio seguente definisce due interfacce COM. Da questo file IDL, Midl.exe genererà il proxy/stub e il marshalling di file di codice e intestazione. Una dissezione riga per riga segue l'esempio.

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

L'istruzione IDL import viene usata qui per inserire un file di intestazione, Mydefs.h, che contiene tipi definiti dall'utente e Unknwn.idl, che contiene la definizione di IUnknown, da cui derivano IFace1 e IFace2.

L'attributo dell'oggetto identifica l'interfaccia come interfaccia oggetto e indica al compilatore MIDL di generare codice proxy/stub anziché stub di client e server RPC. I metodi dell'interfaccia oggetto devono avere un tipo restituito HRESULT, per consentire al meccanismo RPC sottostante di segnalare errori per le chiamate che non riescono a completare a causa di problemi di rete.

L'attributo uuid specifica l'identificatore di interfaccia (IID). Ogni interfaccia, classe e libreria dei tipi deve essere identificata con il proprio identificatore univoco. Usare l'utilità Uuidgen.exe per generare un set di ID univoci per le interfacce e altri componenti.

La parola chiave interface definisce il nome dell'interfaccia. Tutte le interfacce oggetto devono derivare, direttamente o indirettamente, da IUnknown.

Il parametro direzionale specifica un parametro impostato solo dal chiamante. Il parametro out specifica i dati passati al chiamante. L'uso di entrambi gli attributi direzionali in un parametro specifica che il parametro viene usato sia per inviare dati al metodo sia per passare i dati al chiamante.

L'attributo pointer_default specifica il tipo di puntatore predefinito (univoco, ref o ptr) per tutti i puntatori, ad eccezione di quelli inclusi negli elenchi di parametri. Se non viene specificato alcun tipo predefinito, MIDL presuppone che i singoli puntatori siano univoci. Tuttavia, quando si dispone di più livelli di puntatori, è necessario specificare in modo esplicito un tipo di puntatore predefinito, anche se si desidera che il tipo predefinito sia univoco.

Nell'esempio precedente la matrice BkfstStuff[ ] è una matrice conforme, la cui dimensione viene determinata in fase di esecuzione. L'attributo max_is specifica la variabile che contiene il valore massimo per l'indice di matrice.

L'attributo size_is viene usato anche per specificare le dimensioni di una matrice o, come nell'esempio precedente, più livelli di puntatori. Nell'esempio, la chiamata può essere effettuata senza sapere in anticipo quanti dati verranno restituiti.

Esempio2.idl

Nell'esempio IDL seguente (che riutilizza le interfacce descritte nell'esempio IDL precedente) vengono illustrati i vari modi per generare informazioni sulla libreria dei tipi per le interfacce.

//
// 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
 

L'attributo helpstring è facoltativo. È possibile usarlo per descrivere brevemente l'oggetto o per fornire una riga di stato. Queste stringhe della Guida sono leggibili con un visualizzatore oggetti, ad esempio quello fornito con Microsoft Visual Basic.

L'attributo duale in IFace3 crea un'interfaccia che sia un'interfaccia dispatch che un'interfaccia COM. Poiché deriva da IDispatch, un'interfaccia duale supporta l'automazione, ovvero l'attributo oleautomation specificato. IFace3 importa Oaidl.idl per ottenere la definizione di IDispatch.

L'istruzione library definisce la libreria dei tipi ExampleLib, che ha i propri attributi uuid, helpstring e version.

All'interno della definizione della libreria dei tipi, la direttiva importlib introduce una libreria dei tipi compilata. Tutte le definizioni della libreria dei tipi devono essere incluse nella libreria dei tipi di base definita in Stdole32.tlb.

Questa definizione della libreria dei tipi illustra tre modi diversi per includere le interfacce nella libreria dei tipi. IFace3 è incluso semplicemente facendo riferimento all'interno dell'istruzione della libreria.

L'istruzione coclasse definisce una classe di componenti completamente nuova, BkfstComponent, che include due interfacce definite in precedenza, IFace1 e IFace2. L'attributo predefinito definisce IFace1 come interfaccia predefinita.

IFace4 è descritto nell'istruzione della libreria. L'attributo propput in MethodD indica che il metodo esegue un'azione set su una proprietà con lo stesso nome. L'attributo propget indica che il metodo recupera informazioni da una proprietà con lo stesso nome del metodo. L'attributo retval in MethodD definisce un parametro di output che contiene il valore restituito della funzione.