I have some C # program that loads a C ++ DLL, in one of the functions of which an attempt is made to create a COM object. This function returns an interface value.

extern "C" _declspec(dllexport) ISin * __stdcall GetInterface() { HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hr)) { std::cout << "CoInitialize -> FAILED"; return 0; } ISin * pISin = 0; hr = CoCreateInstance(CLSID_CoSin, 0, CLSCTX_INPROC_SERVER, IID_ISin, (LPVOID*)&pISin); if (FAILED(hr)) { std::cout << "CoCreateInstance -> FAILED"; // <-- Выводит в основной программе std::cout << hr; // -2147221164 return 0; } if (pISin == 0) { std::cout << "pISin is null"; } CoUninitialize(); return pISin; } 

Could not correctly invoke the function CoCreateInstance: FAILED (hr) returns true and that's it.

I know that there is a CoCreateInstanceEx function, but I don’t know how to use it and whether it will help here at all. Also, perhaps a problem in choosing CLSCTX.

Your suggestions?

  • And what is the value of hr ? Are you sure the context should be CLSCTX_INPROC_SERVER ? In addition, CoUninitialize must be called strictly after deleting the created object. - VTT

1 answer 1

The return error code -2147221164 is REGDB_E_CLASSNOTREG (Class not registered). This code means that such COM server is not registered in the system. The same error is returned when specifying the wrong server type, for example, if the server is local out-of-proc, and in the dwClsContext parameter dwClsContext specified CLSCTX_INPROC_SERVER instead of the correct CLSCTX_LOCAL_SERVER .

First, check the server type - is it local (.exe) or in-proc (.dll). Alternatively, if the server type is unimportant for you, you can specify CLSCTX_ALL (i.e., anyone is CLSCTX_ALL with you).

If CoCreateInstance returns this error and with the argument CLSCTX_ALL , the server is simply not registered. Check that it is present in the system, and if necessary, register it with the command

 regsvr32 server.dll 

I will also add: CoInitialize and CoUninitialize should be called at the beginning and at the end of the program, respectively, once. You do not need CoInitializeEx , in any case, until you begin to understand COM so that you choose the threading model.

  • CLSCTX_ALL did not help. Tried to run the command you wrote. The following message appeared: "Module" Sin.dll "is loaded, but the entry point in DllRegisterServer was not found." - J. Doe
  • And another such question. If I call CoCreateInstance in a library whose function is trying to get a pointer to an interface, and this library is in a project different from the one in which the COM object was created, then they are in different processes and, therefore, the COM server is local? Must in this case be the extension .exe? - J. Doe Nov.
  • @J. Doe, " DllRegisterServer entry point not found " means that it is not a COM server. Any inproc (.dll) COM server is required to export four functions (in addition to DllMain ) DllCanUnloadNow , DllGetClassObject , DllRegisterServer , and DllUnregisterServer . If this is your server, then most likely you forgot to include the corresponding .def file in the project. - freim
  • @J. Doe, another project does not necessarily mean a different process. But if the process is really different, then this is, of course, an out-of-proc (local) server. The .exe extension is optional, the main thing is that it is a valid PE file. And duly registered, of course. - freim 2:46