Search code examples
c++winapicom

Why no type mismatch in call to CoCreateInstance function in the Windows API?


I'm trying to translate this example of calling the WMI/COM using winapi from C++ to Rust, but there's something I don't understand in the original code. Here's a function call in the C++ code:

hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);

What puzzles me is the type of the first and fourth arguments. Take the fourth argument, for example. If we look at the definition of CoCreateInstance, the fourth argument is of type REFIID which in turn is defined as a *IID where an IID is defined as a GUID. So the fourth argument should be a pointer to a GUID object.

But if you look at what I think is the definition of IID_IWbemLocator, it's defined as a GUID (using the DEFINE_GUID macro). So it looks like we're passing a GUID as an argument when really we should be passing a pointer to a GUID. Why does this code compile?

By comparison, in Rust I have to pass a reference to IID_IWbemLocator.

Apologies if the answer is really simple, I'm pretty unfamiliar with both C++ and the Winapi.


Solution

  • the third argument is of type REFIID which in turn is defined as a *IID where an IID is defined as a GUID. So the third argument should be a pointer to a GUID object.

    The documentation you linked is incorrect. I suspect it was written for C.

    In C++, REFIID and REFCLSID are defined as IID references in Windows headers, like so:

    #ifdef __cplusplus
    #define REFIID const IID &
    #else
    #define REFIID const IID * __MIDL_CONST
    #endif
    
    
    #ifdef __cplusplus
    #define REFCLSID const IID &
    #else
    #define REFCLSID const IID * __MIDL_CONST
    #endif