3
votes

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;
}
1
Same architecture? (32/64bit) ? You could always check the registry to see if it is, in fact, registered properly?WhozCraig
Yes, same physical computer. Compiled with /MACHINE:X86 in both cases. My look at the registry does seem to indicate it is registered.abelenky
Duh. Both of these are wrong. You're passing the UUID of an interface, not of a coclass. You either need CLSID_Calendar, or whoever the coclass id is of the object you're creating. If your header is available, use __uuidof(Calendar) or whatever the coclass that is exposing this interface is actually called. Open the header and look for coclass. You'll find it.WhozCraig
Doh! The working program has ICalendarPtr pDtTm(__uuidof(Calendar)); But I copied ICalendarPtr pDtTm(__uuidof(ICalendar)); to my program. Thank you!abelenky
Mr Lebeau has it already. no worries.WhozCraig

1 Answers

9
votes

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().