c ++ - Broken COM-objektregistrering

Indlæg af Hanne Mølgaard Plasc

Problem



Dette er en fortsættelse af Register implementering af en com interface; først nu har jeg den rigtige kode, der skal debugging.


Jeg har to COM objekter, en der implementerer IAudioSessionEvents og en, der implementerer IClassFactory og producerer det første objekt.


Følgende kode registrerer disse objekter (i overensstemmelse med min forståelse af COM-registrering):


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;
}


Jeg har udeladt RegisterKeyValue (...), sin enkle registrerings kode, som jeg har bekræftet fungerer som beregnet.


Denne kode forsøger at bruge disse COM objekter:


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);


Opkaldet til CoGetClassObject (...) returnerer hr=0x80040111 (ClassFactory kan ikke levere anmodet klasse).


Implementering af DllGetClassObject (pr. 1800 INFORMATION, der peger på ommisionen):


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;
}


Hvad laver jeg galt her? Jeg har mistanke om det i COM-registreringen, men kan ikke finde noget, der faktisk præciserer, hvad der kræves i registreringsdatabasen. Jeg har en slags omvendt manipuleret, hvad jeg gemmer i øjeblikket.

Bedste reference


Denne artikel COM i almindelig C har en ret god beskrivelse, hvordan du skal implementere en COM dll uden at bruge ATL. Som påpeget af 1800 vil DllGetClassObject blive kaldt for at oprette et COM-objekt. Også COM Programmerens Cookbook er en fin reference om COM. [5] [6]