Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Nadat een thread de COM-bibliotheek heeft geïnitialiseerd, is het veilig voor de thread om COM-interfaces te gebruiken. Als u een COM-interface wilt gebruiken, maakt uw programma eerst een exemplaar van een object dat die interface implementeert.
Over het algemeen zijn er twee manieren om een COM-object te maken:
- De module die het object implementeert, kan een functie bieden die speciaal is ontworpen voor het maken van exemplaren van dat object.
- Alternatief biedt COM een generieke functie voor het maken met de naam CoCreateInstance.
Neem bijvoorbeeld het hypothetische Shape-object uit het onderwerp Wat is een COM-interface?. In dat voorbeeld implementeert het Shape-object een interface met de naam IDrawable. De grafische bibliotheek waarmee het Shape object wordt geïmplementeerd, kan een functie exporteren met de volgende handtekening.
// Not an actual Windows function.
HRESULT CreateShape(IDrawable** ppShape);
Met deze functie kunt u als volgt een nieuw Shape object maken.
IDrawable *pShape;
HRESULT hr = CreateShape(&pShape);
if (SUCCEEDED(hr))
{
// Use the Shape object.
}
else
{
// An error occurred.
}
De parameter ppShape is van het type pointer-to-pointer-to-IDrawable. Als u dit patroon nog niet eerder hebt gezien, kan de dubbele indirectie verwarrend zijn.
Houd rekening met de vereisten van de functie CreateShape. De functie moet een IDrawable aanwijzer teruggeven aan de aanroeper. Maar de retourwaarde van de functie wordt al gebruikt voor de fout-/succescode. Daarom moet de aanwijzer worden geretourneerd via een argument voor de functie. De aanroeper geeft een variabele van het type IDrawable* door aan de functie en de functie overschrijft deze variabele met een nieuwe IDrawable aanwijzer. In C++ zijn er slechts twee manieren waarop een functie een parameterwaarde kan overschrijven: door een verwijzing of door een adres. COM gebruikt de laatstgenoemde techniek, pass-by-address. En het adres van een aanwijzer is een aanwijzer-naar-aanwijzer, dus het parametertype moet IDrawable**zijn.
Hier volgt een diagram om te visualiseren wat er aan de hand is.
De functie CreateShape gebruikt het adres van pShape- (&pShape) om een nieuwe aanwijzerwaarde naar pShape-te schrijven.
CoCreateInstance: een algemene manier om objecten te maken
De functie CoCreateInstance biedt een algemeen mechanisme voor het maken van objecten. Als u wilt weten CoCreateInstance, moet u er rekening mee houden dat twee COM-objecten dezelfde interface kunnen implementeren en dat één object twee of meer interfaces kan implementeren. Een algemene functie waarmee objecten worden gemaakt, heeft dus twee stukjes informatie nodig.
- Welk object maken?
- Welke interface moet worden opgehaald uit het object.
Maar hoe geven we deze informatie aan wanneer we de functie aanroepen? In COM wordt een object of interface geïdentificeerd door het toe te wijzen aan een 128-bits nummer, een globally unique identifier (GUID). GUID's worden gegenereerd op een manier die ze effectief uniek maakt. GUID's zijn een oplossing voor het probleem van het maken van unieke id's zonder centrale registratie-instantie. GUID's worden ook wel universeel unieke id's (UUID's) genoemd. Voordat COM bestond, werden ze gebruikt in de DCE/RPC (Distributed Computing Environment/Remote Procedure Call). Er bestaan verschillende algoritmen voor het maken van nieuwe GUID's. Niet al deze algoritmen garanderen strikt uniekheid, maar de kans dat per ongeluk twee keer dezelfde GUID-waarde wordt gemaakt, is extreem klein, effectief nul. GUID's kunnen worden gebruikt om een soort entiteit te identificeren, niet alleen objecten en interfaces. Dat is echter het enige gebruik dat betrekking heeft op ons in deze module.
De Shapes-bibliotheek kan bijvoorbeeld twee GUID-constanten declareren:
extern const GUID CLSID_Shape;
extern const GUID IID_IDrawable;
(U kunt aannemen dat de werkelijke 128-bits numerieke waarden voor deze constanten elders worden gedefinieerd.) De constante CLSID_Shape identificeert het Shape object, terwijl de constante IID_IDrawable de IDrawable interface identificeert. Het voorvoegsel 'CLSID' staat voor klasse-iden het voorvoegsel IID- staat voor interface-id. Dit zijn standaardnaamconventies in COM.
Op basis van deze waarden maakt u als volgt een nieuw Shape exemplaar:
IDrawable *pShape;
hr = CoCreateInstance(CLSID_Shape, NULL, CLSCTX_INPROC_SERVER, IID_IDrawable,
reinterpret_cast<void**>(&pShape));
if (SUCCEEDED(hr))
{
// Use the Shape object.
}
else
{
// An error occurred.
}
De functie CoCreateInstance heeft vijf parameters. De eerste en vierde parameters zijn de klasse-id en interface-id. In feite vertellen deze parameters de functie: "Maak het Shape-object aan en geef me een verwijzing naar de IDrawable-interface."
Stel de tweede parameter in op NULL-. (Zie het onderwerp Aggregation in de COM-documentatie voor meer informatie over de betekenis van deze parameter.) De derde parameter gebruikt een set vlaggen waarvan het belangrijkste doel is om de uitvoeringscontext op te geven voor het object. De uitvoeringscontext geeft aan of het object wordt uitgevoerd in hetzelfde proces als de toepassing; in een ander proces op dezelfde computer; of op een externe computer. In de volgende tabel ziet u de meest voorkomende waarden voor deze parameter.
| Vlag | Beschrijving |
|---|---|
| CLSCTX_INPROC_SERVER | Hetzelfde proces. |
| CLSCTX_LOCAL_SERVER | Verschillend proces, dezelfde computer. |
| CLSCTX_REMOTE_SERVER | Andere computer. |
| CLSCTX_ALL | Gebruik de meest efficiënte optie die het object ondersteunt. (De rangschikking, van meest efficiënt tot minst efficiënt, is: in-process, out-of-process en cross-computer.) |
In de documentatie voor een bepaald onderdeel kunt u zien welke uitvoeringscontext het object ondersteunt. Als dat niet het geval is, gebruikt u CLSCTX_ALL. Als u een uitvoeringscontext aanvraagt die het object niet ondersteunt, retourneert de functie CoCreateInstance de foutcode REGDB_E_CLASSNOTREG. Deze foutcode kan ook aangeven dat de CLSID niet overeenkomt met een onderdeel dat is geregistreerd op de computer van de gebruiker.
De vijfde parameter voor CoCreateInstance ontvangt een aanwijzer naar de interface. Omdat CoCreateInstance een algemeen mechanisme is, kan deze parameter niet sterk worden getypt. In plaats daarvan is het gegevenstype void**en moet de aanroeper het adres van de pointer naar een void** type converteren. Dat is het doel van de reinterpret_cast in het vorige voorbeeld.
Het is van cruciaal belang om de retourwaarde van CoCreateInstancete controleren. Als de functie een foutcode retourneert, is de COM-interfaceaanwijzer ongeldig en kan het programma vastlopen.
Intern gebruikt de functie CoCreateInstance verschillende technieken om een object te maken. In het eenvoudigste geval wordt de klasse-id in het register opgezoekd. De registervermelding wijst naar een DLL of EXE die het object implementeert. CoCreateInstance kan ook informatie gebruiken uit een COM+-catalogus of een side-by-side manifest. De details zijn echter transparant voor de beller. Zie COM-clients en -serversvoor meer informatie over de interne details van CoCreateInstance.
Het Shapes voorbeeld dat we hebben gebruikt, is enigszins gemaakt, dus laten we nu kijken naar een praktijkvoorbeeld van COM in actie: het weergeven van het dialoogvenster Openen waarmee de gebruiker een bestand kan selecteren.
Volgende
voorbeeld: het dialoogvenster Openen