Anatomia pliku IDL
Te przykładowe pliki IDL przedstawiają podstawowe konstrukcje definicji interfejsu. Alokacja pamięci, niestandardowe marshaling i asynchroniczne komunikaty to tylko kilka funkcji, które można zaimplementować w niestandardowym interfejsie COM. Atrybuty MIDL służą do definiowania interfejsów COM. Aby uzyskać więcej informacji na temat implementowania interfejsów i bibliotek typów, w tym podsumowanie atrybutów MIDL, zobacz Definicje interfejsu i biblioteki typów w Przewodniku i dokumentacji programisty MIDL. Aby uzyskać pełne odwołanie do wszystkich atrybutów, słów kluczowych i dyrektyw MIDL, zobacz MIDL Language Reference.
Example.idl
Poniższy przykładowy plik IDL definiuje dwa interfejsy COM. Na podstawie tego pliku IDL Midl.exe wygeneruje pliki proxy/wycinków i kodu marshalingowego oraz nagłówków. Zgodnie z przykładem jest rozcięcie linii po linii.
//
// 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);
};
W tym miejscu jest używana instrukcja importowaniaIDL, aby wprowadzić plik nagłówka Mydefs.h, który zawiera typy zdefiniowane przez użytkownika i Unknwn.idl, który zawiera definicję IUnknown, z którego pochodzą klasy IFace1 i IFace2.
Obiekt atrybut identyfikuje interfejs jako interfejs obiektu i informuje kompilator MIDL o wygenerowaniu kodu proxy/wycinku zamiast łączników klienta I serwera RPC. Metody interfejsu obiektu muszą mieć typ zwracany HRESULT, aby umożliwić bazowy mechanizm RPC zgłaszanie błędów wywołań, które nie powiodły się z powodu problemów z siecią.
Atrybut uuid określa identyfikator interfejsu (IID). Każdy interfejs, klasa i biblioteka typów muszą być identyfikowane z własnym unikatowym identyfikatorem. Użyj narzędzia Uuidgen.exe, aby wygenerować zestaw unikatowych identyfikatorów dla interfejsów i innych składników.
Interfejs słowo kluczowe definiuje nazwę interfejsu. Wszystkie interfejsy obiektów muszą pochodzić bezpośrednio lub pośrednio z IUnknown.
w parametr kierunkowy określa parametr ustawiany tylko przez obiekt wywołujący. Parametr określa dane przekazywane z powrotem do obiektu wywołującego. Użycie obu atrybutów kierunkowych w jednym parametrze określa, że parametr jest używany zarówno do wysyłania danych do metody, jak i przekazywania danych z powrotem do obiektu wywołującego.
Atrybut pointer_default określa domyślny typ wskaźnika (unikatowy, reflub ptr) dla wszystkich wskaźników z wyjątkiem tych uwzględnionych na listach parametrów. Jeśli nie określono typu domyślnego, MIDL zakłada, że pojedyncze wskaźniki są unikatowe. Jeśli jednak masz wiele poziomów wskaźników, musisz jawnie określić domyślny typ wskaźnika, nawet jeśli chcesz, aby domyślny typ był unikatowy.
W poprzednim przykładzie tablica BkfstStuff[ ] jest zgodną tablicą, której rozmiar jest określany w czasie wykonywania. Atrybut max_is określa zmienną zawierającą maksymalną wartość indeksu tablicy.
Atrybut size_is służy również do określania rozmiaru tablicy lub, jak w poprzednim przykładzie, wielu poziomów wskaźników. W tym przykładzie można wykonać wywołanie bez wcześniejszego poznania ilości danych, które zostaną zwrócone.
Example2.idl
Poniższy przykład IDL (który ponownie używa interfejsów opisanych w poprzednim przykładzie IDL) przedstawia różne sposoby generowania informacji o bibliotece typów dla interfejsów.
//
// 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
Atrybut pomocnika jest opcjonalny; służy do krótkiego opisywania obiektu lub podania wiersza stanu. Te ciągi pomocy można odczytać za pomocą przeglądarki obiektów, takiej jak ta dostarczana z programem Microsoft Visual Basic.
Atrybut podwójnej w interfejsie IFace3 tworzy interfejs, który jest zarówno interfejsem wysyłania, jak i interfejsem COM. Ponieważ pochodzi on z IDispatch, podwójny interfejs obsługuje automatyzację, co określa atrybut oleautomation. Program IFace3 importuje plik Oaidl.idl, aby uzyskać definicję IDispatch.
Instrukcjabibliotekidefiniuje bibliotekę typów ExampleLib, która ma własne atrybuty uuid, ułatwiającei atrybuty wersji.
W definicji biblioteki typów dyrektywa importlib wprowadza skompilowaną bibliotekę typów. Wszystkie definicje bibliotek typów powinny zawierać podstawową bibliotekę typów zdefiniowaną w pliku Stdole32.tlb.
Ta definicja biblioteki typów przedstawia trzy różne sposoby dołączania interfejsów w bibliotece typów. Element IFace3 jest dołączany tylko przez odwołanie do niej w instrukcji biblioteki.
Instrukcja coclass definiuje całkowicie nową klasę składników BkfstComponent, która zawiera dwa wcześniej zdefiniowane interfejsy, IFace1 i IFace2. Domyślny atrybut wyznacza interfejs IFace1 jako interfejs domyślny.
IFace4 jest opisany w instrukcji biblioteki. Atrybut propput w metodzie MethodD wskazuje, że metoda wykonuje akcję zestawu we właściwości o tej samej nazwie. Atrybut propget wskazuje, że metoda pobiera informacje z właściwości o tej samej nazwie co metoda. Atrybut ponownego retwalowania w metodzie MethodD wyznacza parametr wyjściowy zawierający zwracaną wartość funkcji.