Обикновено бихте използвали CoCreateInstance()
за инстанциране на обект от COM DLL. Когато направите това, няма нужда първо да зареждате DLL и да получавате proc адреси, както бихте трябвало да направите с нормален DLL. Това е така, защото Windows "знае" за типовете, които COM DLL имплементира, в каква DLL са имплементирани и как да ги инстанцира. (Ако приемем, разбира се, че COM DLL е регистриран, което обикновено е).
Да предположим, че имате COM DLL с IDog интерфейса, който искате да използвате. В този случай,
dog.idl
interface IDog : IUnknown
{
HRESULT Bark();
};
coclass Dog
{
[default] Interface IDog;
};
myCode.cpp
IDog* piDog = 0;
CoCreateInstance(CLSID_DOG, 0, CLSCTX_INPROC_SERVER, IID_IDOG, &piDog); // windows will instantiate the IDog object and place the pointer to it in piDog
piDog->Bark(); // do stuff
piDog->Release(); // were done with it now
piDog = 0; // no need to delete it -- COM objects generally delete themselves
Всички тези неща за управление на паметта обаче могат да станат доста груби и ATL предоставя интелигентни указатели, които правят задачата за инстанциране и управление на тези обекти малко по-лесна:
CComPtr<IDog> dog;
dog.CoCreateInstance(CLSID_DOG);
dog->Bark();
РЕДАКТИРАНЕ:
Когато казах по-горе това:
Windows „знае“ за типовете, които COM DLL имплементира [...и] в какви DLL са имплементирани
...наистина премълчах как точно Windows знае това. Не е магия, въпреки че в началото може да изглежда малко окултно.
COM библиотеките идват с библиотеки за типове, които изброяват интерфейсите и CoClasses, които библиотеката предоставя. Тази библиотека с типове е под формата на файл на вашия твърд диск -- много често тя е вградена директно в същата DLL или EXE като самата библиотека. Windows знае къде да намери Type Library и самата COM Library, като търси в системния регистър на Windows. Записите в регистъра казват на Windows къде на твърдия диск се намира DLL.
Когато извикате CoCreateInstance
, Windows търси clsid в системния регистър на Windows, намира съответния DLL, зарежда го и изпълнява правилния код в DLL, който имплементира COM обекта.
Как тази информация влиза в системния регистър на Windows? Когато се инсталира COM DLL, той се регистрира. Това обикновено се прави чрез стартиране на regsvr32.exe, което от своя страна зарежда вашата DLL в паметта и извиква функция с име DllRegisterServer
. Тази функция, внедрена във вашия COM сървър, добавя необходимата информация към регистъра. Ако използвате ATL или друга COM рамка, това вероятно се прави под капака, така че да не се налага да взаимодействате директно с регистъра. DllRegisterServer
трябва да се извика само веднъж, по време на инсталиране.
Ако се опитате да извикате CoCreateInstance
за COM обект, който все още не е регистриран чрез процеса regsvr32
/DllRegisterServer
, тогава CoCreateInstance
ще се провали с грешка, която казва:
Класът не е регистриран
За щастие решението за това е просто да извикате regsvr32
на вашия COM сървър и след това да опитате отново.
person
John Dibling
schedule
02.02.2010