Сломанная регистрация COM-объекта - PullRequest
3 голосов
/ 04 апреля 2009

Это продолжение Реализация реализации com-интерфейса ; только теперь у меня есть актуальный код, который требует отладки.

У меня есть два COM-объекта, один из которых реализует IAudioSessionEvents, а другой - IClassFactory и создает первый объект.

Следующий код регистрирует эти объекты (в соответствии с моим пониманием регистрации COM):

BOOL RegisterClassManually(WCHAR* szGuid, WCHAR* szDllPath)
{
WCHAR szKeyName[1024];
wsprintf(szKeyName, TEXT("Software\\Classes\\CLSID\\%s"), szGuid);

if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, NULL, TEXT(DESCRIPTION_CONST))) return false;

wsprintf(szKeyName, TEXT("Software\\Classes\\CLSID\\%s\\InprocServer32"), szGuid);

if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, NULL, szDllPath)) return false;
if(!RegisterKeyValue(HKEY_CURRENT_USER, szKeyName, TEXT("ThreadingModel"), TEXT("Apartment"))) return false;

return true;
}

STDAPI DllRegisterServer()
{
//Write data to HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{GUID}
// Also ""\\InProcServer32
// Also "".ThreadingModel = "Apartment"

WCHAR* szGuid;
WCHAR szDllPath[512];
StringFromCLSID(CLSID_AudioEventsFactory, &szGuid);

if(g_dllModule == NULL) return SELFREG_E_CLASS;

GetModuleFileName(g_dllModule, szDllPath, 512);

if(!RegisterClassManually(szGuid, szDllPath)) return SELFREG_E_CLASS;

StringFromCLSID(CLSID_AudioEvents, &szGuid);

if(!RegisterClassManually(szGuid, szDllPath)) return SELFREG_E_CLASS;

return S_OK;
}

Я опустил RegisterKeyValue (...), его простой код реестра, который, как я подтвердил, работает как задумано.

Этот код пытается использовать следующие COM-объекты:

IAudioSessionEvents* listener = NULL;

IClassFactory* factory = NULL;

//Fails on this call
hr = CoGetClassObject(CLSID_AudioEventsFactory, CLSCTX_ALL, NULL, __uuidof(IClassFactory), (void**)&factory);

if(hr != S_OK)
{
    ... Report Error ...
}

hr = factory->CreateInstance(NULL, __uuidof(IAudioSessionEvents), (void**)&listener);

Вызов CoGetClassObject (...) возвращает hr = 0x80040111 (ClassFactory не может предоставить запрошенный класс).

Реализация DllGetClassObject (за 1800 ИНФОРМАЦИЯ, указывающую на пропуск):

STDAPI DllGetClassObject(const CLSID& clsid,
                     const IID& iid,
                     void** ppv)
{

if (clsid == __uuidof(IClassFactory))
{
    AudioEventsFactory *pFact = new AudioEventsFactory;
    if (pFact == NULL)
        return E_OUTOFMEMORY;
    else
    {
        return pFact->QueryInterface(iid , ppv);
    }
}

return CLASS_E_CLASSNOTAVAILABLE;
}

Что я здесь не так делаю? Я подозреваю, что это в регистрации COM, но не могу найти ничего, что фактически выкладывает именно то, что требуется в реестре. Я как бы перепроектировал то, что храню в данный момент.

1 Ответ

2 голосов
/ 04 апреля 2009

Эта статья COM на простом C содержит довольно хорошее описание того, как реализовать COM-библиотеку без использования ATL. Как указано в 1800 году, DllGetClassObject будет вызываться для создания COM-объекта. Также Поваренная книга программиста COM является хорошим справочником о COM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...