简体   繁体   中英

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM