Zugriff auf COM-Funktionen mittels plain-C

By dose | November 13, 2005
Under: technical stuff, Uncategorized

Alles begann damit, dass ich mir in den Kopf gesetzt habe, das Windows Adressbuch auszulesen, um Telefonnummern für mein Miranda WebSMS – Adressbuch zu sammeln.
Durch kurzes Suchen bin ich dann auch recht schnell auf die Funktion WABOpen gestoßen, um gleich darauf aufzuschrecken: Oh, was haben wie denn da? COM? Hilfe!
Nachdem ich am liebsten in plain C entwickle hat mich das zurückgegebene Interface gleich etwas verunsichert. Sieht verdächtig nach C++ aus. Ein näherer Blick auf das Interface hat diesen Verdacht noch verhärtet. Also habe ich nach Alternativen gesucht, aber die einzige Möglichkeit, das Adressbuch auszulesen ist über COM. Na gut, dann muss das Teil aber über C auch ansprechbar sein, schließlich baut die ganze WIN32-API darauf auf. Daher habe ich mich etwas über COM schlau gemacht. Wo ist der beste Ort hierfür? Klar, in Raymond Chens Weblog The Old New Thing.
Ich habe auch gleich eine kurze Erklärung des COM Interfaces gefunden, was meinen Verdacht, dass das Zeugs doch mittels C ansprechbar ist, bestätigt hat. Na juhu, dann auf ans Werk!
Die Beispiele, die man zum Windows-Adressbuch im Internet so findet sind leider so gut wie alle C++.
Und in C++ kann man die COM-Interfaces wie Klassen ansprechen, mittels iInterface->Function(Param1, Param2, ...)
Wer das jedoch in C versucht, wird schnell feststellen, dass die COM-Struktur nicht einfach direkt Function-Pointer auf die entsprechenden Funktionen enthält und das damit auf dieselbe Weise auch in C funktioniert. Viel mehr baut COM die C++ Klassenfunktionalität mithilfe von sogenannten VTABLEs nach. Diese enthalten die entsprechenden Function Pointer auf die Startadressen der jeweiligen Funktionen . Die Funktionen ihrerseits bekommen als ersten Parameter den aus C++ bekannten this-pointer mit übergeben.
In C++ wird dies entsprechend automatisch aufgelöst, in C muss man jedoch manuell auf dien vTable zugreifen. Um das Ganze kurz zu fassen, wie man nun auf COM-Funktionen in C zugreift, zeige ich das Ganze anhand der Funktion IAddrBook::GetPAB:


LPADRBOOK lpAdrBook;
LPWABOBJECT lpWABObject;
ULONG lpcbEntryID;
ENTRYID *lpEntryID;

WABOpen (&lpAdrBook, lpWABObject, NULL, 0);
// The C++ way:
lpAdrBook->GetPAB (&lpcbEntryID, &lpEntryID);
// The C way:
lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &lpcbEntryID, &lpEntryID);

Also ein C einfach die Funktion innerhalb des Strukturmembers lpVtbl suchen und
als ersten PArameter das Interface mitübergeben. Das ist alles.

Leave a Comment

Name:

E-Mail :

Subscribe :
Website :

Comments :