2009-04-04 7 views
3

Ceci est la suite de Register implementation of a com interface; seulement maintenant j'ai le code réel qui a besoin de déboguer.Enregistrement d'objet COM brisé

J'ai deux objets COM, un qui implémente IAudioSessionEvents et un qui implémente IClassFactory et produit le premier objet.

Le code suivant enregistre ces objets (selon ma compréhension de l'enregistrement 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; 
} 

J'ai omis RegisterKeyValue (...), son code simple registre que j'ai confirmé que les travaux prévu.

Ce code tente d'utiliser ces objets 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); 

L'appel à CoGetClassObject (...) retourne hr = 0x80040111 (ClassFactory ne peut pas fournir la classe demandée).

mise en œuvre de DllGetClassObject (par 1800 INFORMATIONS pointant vers le ommision):

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

ce que je fais mal ici? Je suppose que c'est dans l'enregistrement COM, mais ne trouve rien qui précise exactement ce qui est nécessaire dans le registre. J'ai en quelque sorte inversé ce que je stocke pour le moment.

Répondre

2

Cet article COM in plain C a une description assez bonne de la façon dont vous devez implémenter une DLL COM sans utiliser ATL. Comme indiqué par 1800, DllGetClassObject sera appelé pour créer un objet COM. Aussi The COM Programmer's Cookbook est une belle référence sur COM.