Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

COM Error: Class not registered (I'm sure it is)

Tags:

c++

registry

com

I have a large complex program that has a COM problem.
I'm attempting to write a much smaller SSCCE program to reduce the problem.

However, no matter what I try, the CoCreateInstance in my SSCCE keeps coming back with

hr 0x80040154 (Class Not Registered)  (For CoCreateInstance)
0x800706B5: The interface is unknown. (for ICalendarPtr constructor)

I'm using the same GUIDs and other parameters from the bigger program.
(turns out I wasn't using the same guids. Just similar ones)

I'm linking to the same libraries, and have the same DLLs available (both locally and properly registered in Program Files).

I'm not a Registry expert, but looking through the registry, I do find the Interface and Class GUID look to be properly registered, with a TypeLib-key that refers to a DLL that is present and accessible.

Can you think of something I might be missing that would cause one program to create a COM object successfully, but another to say the class isn't registered?

Code:

_COM_SMARTPTR_TYPEDEF(ICalendar, __uuidof(ICalendar));

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);

    CLSID classID = __uuidof(ICalendar);
    REFIID iid = __uuidof(IUnknown);
    LPVOID pRet;
    HRESULT hr = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, iid, &pRet);
    // Result: 0x80040154 Class not registered

    GUID guid = __uuidof(ICalendar);
    ICalendarPtr pDtTm(guid);
    // Result: First-chance exception at 0x773dc41f in COMTest.exe: 0x800706B5: The interface is unknown.


    return 0;
}
like image 583
abelenky Avatar asked Oct 21 '25 16:10

abelenky


1 Answers

CLSID classID = __uuidof(ICalendar);

This is wrong. __uuidof() retrieves an interface's IID, not its CLSID. When calling CoCreateInstance(), you need to use the CLSID in the 1st parameter and the IID in the 4th parameter, eg:

ICalendar *pRet;
HRESULT hr = CoCreateInstance(CLSID_Calendar, NULL, CLSCTX_INPROC_SERVER, __uuidof(ICalendar), (void**)&pRet);

When using the constructor of an interface smart wrapper, you need to use the CLSID, eg:

ICalendarPtr pDtTm(CLSID_Calendar);

There is no compiler syntax for retrieving an interface's CLSID. You have to import the interface's TypeLibrary and then use the generated .h file to get the definitions, or else do a lookup of the Registry at runtime, such as with CLSIDFromProgID().

like image 68
Remy Lebeau Avatar answered Oct 23 '25 07:10

Remy Lebeau