Это продолжение Реализация реализации 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, но не могу найти ничего, что фактически выкладывает именно то, что требуется в реестре. Я как бы перепроектировал то, что храню в данный момент.