Search code examples
c++comautomationolelabview

OLE automation problems with C++ - "Class not registered"


I'm trying to port a LabView program to C++, and the OLE calls it contains are giving me some trouble.

The LabView program starts out by doing an "Automation open", i.e. getting a reference to the interface "XLib.XInterface" (LabView calls this expression the "ActiveX class"), then calls the method QA found in the interface and finally closes the reference again. I think LabView gets its info on the interface from the type library, but I'm not entierly sure.

I've tried to adapt some code for Word automation I found: http://www.codeproject.com/KB/office/MSOfficeAuto.aspx

CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"XConfig.XInterface", &clsid);

IDispatch *pWApp;
if(SUCCEEDED(hr))
{
    hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, 
                          IID_IDispatch, (void **)&pWApp);
}
// etc.

The program is successful in looking up the CLSID, but CoCreateInstance fails, claiming that the class is not registered. I've also tried entering the CLSID from the type library directly, bypassing CLSIDFromProgID, but yielding the same result. Needless to say that the LabView program works fine, and the C++ code I'm using has no trouble at all to create an instance of Word when using the progID "Word.Application". The interface in question looks like this:

[
   odl,
   uuid(33AAA2DA-70EB-48EE-ACA7-DD0D1F5CAF2D),
   helpstring("XInterface Interface"),
   dual,
   oleautomation
]
interface XInterface : IDispatch {
   [id(0x00000001), helpstring("method QA")]
   HRESULT QA();
   [id(0x00000002), helpstring("method LoadFromDisk")]
   HRESULT LoadFromDisk();
   ...

As you may have noticed, OLE is kind of new to me (most likely, that's a part of the problem). Any hints would be greatly appreciated. Thanks.


Solution

  • OK, I think I figured it out by myself, even though I don't fully understand my solution. Anyway, when I use

    hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IDispatch,
                (void **)&pWApp);
    

    it seems to work; at least I don't get the "class not registered" error anymore. The difference is replacing the argument CLSCTX_LOCAL_SERVER with CLSCTX_ALL. I think it's got something to do with the fact that I'm using a dll. Does anyone have a more insightful explaination?