Так как СОМ преобразует
HRESULT DllGetClassObject(
[in] REFCLSID rclsid,
// which class object?
// какой объект класса?
[in] REFIID riid,
// which interface?
// какой интерфейс?
[out, ii
// разместить его здесь!
Для удобства и эффективности данный сервер может содержать код для более чем одного класса. Первый параметр
Рассмотрим сервер, реализующий три класса:
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
// define a singleton class object for each class
// определяем одноэлементный объект класса
// для каждого класса
static GorillaClass
static ChimpClass
else if (rclsid == CLSI
else if (rclsid == CLSI
// if we get to here, rclsid is a class we don't implement,
// so fail with well-known error code
// если мы добрались сюда, то rclsid – это класс, который
// мы не реализуем, поэтому сбой с известным кодом ошибки
*ppv = 0;
return CLAS
}
Заметим, что приведенный код не заботится о том, какой интерфейс объявляется каждым из объектов класса. Он просто отправляет запрос
Следующий псевдокод показывает, как API-функция
// pseudo-code from OLE32.DLL
// псевдокод из OLE32.DLL
HRESULT CoGetClassObject(REFCLSID rclsid, DWORD dwClsCtx, COSERVERINFO *pcsi , REFIID riid, void **ppv)
{
HRESULT hr = REGD
*ppv = 0; if (dwClsCtx & CLSCT
// look in table of already loaded servers in this process
// просматриваем таблицу уже загруженных серверов внутри
// этого процесса pfnGCO = LookupInClassTable(rclsid, dwClsCtx);
if (pfnGCO == 0) {
// not loaded yet!
// еще не загружен!
// ask class store or registry for DLL name
// запрашиваем DLL-имя в хранилище классов или в реестре
char szFileName[MA
if (SUCCEEDED(hr))
{
// try to load the DLL and scrape out DllGetClassObject
// пытаемся загрузить DLL и вытащить DllGetClassObject
HINSTANCE hInst = LoadLibrary(szFileName);
if (hInst == 0) return C
pfnGCO = GetProcAddress(hInst, «DllGetClassObject»);
if (pfnGCO == 0) return C
// cache DLL for later use
// кэшируем DLL для дальнейшего использования InsertInClassTable(rclsid, dwClsCtx, hInst, pfnGCO);
}
}
// call function to get pointer to class object
// вызываем функцию для получения указателя на объект класса
hr = (*pfnGCO)(rclsid, riid, ppv);
}
if ((dwClsCtx & (CLSCT
{
// handle out-of-proc/remote request
// обрабатываем внепроцессный/удаленный запрос
}
return hr;
}