Anatomie einer IDL-Datei
Diese IDL-Beispieldateien veranschaulichen die grundlegenden Konstrukte der Schnittstellendefinition. Speicherzuordnung, benutzerdefiniertes Marshalling und asynchrones Messaging sind nur einige der Features, die Sie in einer benutzerdefinierten COM-Schnittstelle implementieren können. MIDL-Attribute werden verwendet, um COM-Schnittstellen zu definieren. Weitere Informationen zum Implementieren von Schnittstellen und Typbibliotheken, einschließlich einer Zusammenfassung der MIDL-Attribute, finden Sie unter Schnittstellendefinitionen und Typbibliotheken im MIDL-Programmiererhandbuch und referenz. Eine vollständige Referenz zu allen MIDL-Attributen, Schlüsselwörtern und Direktiven finden Sie in der MIDL-Sprachreferenz.
Example.idl
Die folgende IDL-Beispieldatei definiert zwei COM-Schnittstellen. Aus dieser IDL-Datei generiert Midl.exe Proxy-/Stub- und Marshallingcode und Headerdateien. Dem Beispiel folgt eine Zeilen-für-Zeilen-Dissektion.
//
// 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);
};
Die IDL-Import-Anweisung wird hier verwendet, um eine Headerdatei einzubringen, Mydefs.h, die benutzerdefinierte Typen enthält, und Unknwn.idl, die die Definition von IUnknown enthält, von der IFace1 und IFace2 abgeleitet werden.
Das Object-Attribut identifiziert die Schnittstelle als Objektschnittstelle und weist den MIDL-Compiler an, Proxy-/Stubcode anstelle von RPC-Client- und Server-Stubs zu generieren. Objektschnittstellenmethoden müssen über den Rückgabetyp HRESULT verfügen, damit der zugrunde liegende RPC-Mechanismus Fehler für Aufrufe melden kann, die aufgrund von Netzwerkproblemen nicht abgeschlossen werden können.
Das Attribut uuid gibt den Schnittstellenbezeichner (Interface Identifier, IID) an. Jede Schnittstelle, Klasse und Typbibliothek muss mit einem eigenen eindeutigen Bezeichner identifiziert werden. Verwenden Sie das Hilfsprogramm Uuidgen.exe, um eine Reihe eindeutiger IDs für Ihre Schnittstellen und andere Komponenten zu generieren.
Die Schnittstelle Schlüsselwort (keyword) definiert den Schnittstellennamen. Alle Objektschnittstellen müssen direkt oder indirekt von IUnknown abgeleitet werden.
Der in directional-Parameter gibt einen Parameter an, der nur vom Aufrufer festgelegt wird. Der Out-Parameter gibt Daten an, die an den Aufrufer zurückgegeben werden. Die Verwendung beider Richtungsattribute für einen Parameter gibt an, dass der Parameter sowohl zum Senden von Daten an die -Methode als auch zum Zurückgeben von Daten an den Aufrufer verwendet wird.
Das pointer_default-Attribut gibt den Standardzeigertyp (eindeutig, ref oder ptr) für alle Zeiger an, mit Ausnahme der in Parameterlisten enthaltenen Zeiger. Wenn kein Standardtyp angegeben ist, geht MIDL davon aus, dass einzelne Zeiger eindeutig sind. Wenn Sie jedoch über mehrere Zeigerebenen verfügen, müssen Sie explizit einen Standardzeigertyp angeben, auch wenn der Standardtyp eindeutig sein soll.
Im vorherigen Beispiel ist das Array BkfstStuff[ ] ein konformes Array, dessen Größe zur Laufzeit bestimmt wird. Das attribut max_is gibt die Variable an, die den Maximalwert für den Arrayindex enthält.
Das size_is-Attribut wird auch verwendet, um die Größe eines Arrays oder, wie im vorherigen Beispiel, mehrere Zeigerebenen anzugeben. Im Beispiel kann der Aufruf erfolgen, ohne im Voraus zu wissen, wie viele Daten zurückgegeben werden.
Example2.idl
Das folgende IDL-Beispiel (das die im vorherigen IDL-Beispiel beschriebenen Schnittstellen wiederverwendet) zeigt die verschiedenen Möglichkeiten zum Generieren von Typbibliotheksinformationen für Schnittstellen.
//
// 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
Das helpstring-Attribut ist optional. Sie verwenden sie, um das Objekt kurz zu beschreiben oder eine status Zeile bereitzustellen. Diese Hilfezeichenfolgen sind mit einem Objektbrowser wie dem mit Microsoft Visual Basic bereitgestellten lesbar.
Das Dual-Attribut in IFace3 erstellt eine Schnittstelle, die sowohl eine Dispatch-Schnittstelle als auch eine COM-Schnittstelle ist. Da sie von IDispatch abgeleitet ist, unterstützt eine duale Schnittstelle Automation, was das oleautomation-Attribut angibt. IFace3 importiert Oaidl.idl, um die Definition von IDispatch zu erhalten.
Die library-Anweisung definiert die ExampleLib-Typbibliothek, die über eigene uuid-, helpstring- und versionsattribute verfügt.
Innerhalb der Typbibliotheksdefinition enthält die Importlib-Anweisung eine kompilierte Typbibliothek. Alle Typbibliotheksdefinitionen sollten die in Stdole32.tlb definierte Basistypbibliothek einbinden.
Diese Typbibliotheksdefinition veranschaulicht drei verschiedene Möglichkeiten, Schnittstellen in die Typbibliothek einzuschließen. IFace3 wird lediglich durch Verweisen in die Library-Anweisung aufgenommen.
Die coclass-Anweisung definiert eine völlig neue Komponentenklasse, BkfstComponent, die zwei zuvor definierte Schnittstellen enthält, IFace1 und IFace2. Das Standardattribute legt IFace1 als Standardschnittstelle fest.
IFace4 wird in der Library-Anweisung beschrieben. Das propput-Attribut für MethodD gibt an, dass die -Methode eine festgelegte Aktion für eine Eigenschaft mit demselben Namen ausführt. Das propget-Attribut gibt an, dass die -Methode Informationen aus einer Eigenschaft mit demselben Namen wie die -Methode abruft. Das retval-Attribut in MethodD gibt einen Ausgabeparameter an, der den Rückgabewert der Funktion enthält.