Why can I call StringFromCLSID even without calling CoInitializeEx before?

I am learning COM via C ++. From MSDN :

Applications are required to use CoInitializeEx before they make other calls to the COM library, except for memory allocation functions.

Memory allocation functions CoTaskMemAlloc

and CoTaskMemFree

in my opinion.

But I see my "Hello World" works perfectly with function calls CoInitializeEx

and CoUninitialize

without them. In my code, I am using the function StringFromCLSID

declared in the header combaseapi.h

. So this is a COM function in my opinion. My code:

/* entry_point.cpp */
#include "Tools.h"
#include <objbase.h>

int main(){
  HRESULT hr = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
  if (FAILED(hr)){
    trace("Can't initialize COM for using in the current thread.");
    keep_window_opened();
    return 1;
  }
  // {D434CF7D-2CDD-457A-A4EF-5822D629CE83}
  static const CLSID clsid =
  { 0xd434cf7d, 0x2cdd, 0x457a, { 
    0xa4, 0xef, 0x58, 0x22, 0xd6, 0x29, 0xce, 0x83 } };

  const size_t SIZE = 39;
  wchar_t* wch = nullptr;
  hr = ::StringFromCLSID(clsid, &wch);
  if (FAILED(hr)){
    trace("Can't convert CLSID to wchar_t array.");
  }
  else{
    trace("CLSID converted to wchar_t array.");
    char mch[SIZE];
    size_t count = 0;
    int result = ::wcstombs_s(&count, mch, wch, SIZE);
    if (result){
      trace("Can't convert wchar_t array to char array.");
    }
    else{
      trace(mch);
    }
    ::CoTaskMemFree(wch);
  }
  ::CoUninitialize();

  keep_window_opened();
  return 0;
}

      

If I remove the function calls CoInitializeEx

and CoUninitialize

then my code works. I expected this to not work ...

Why StringFromCLSID

does it even work without calling CoInitializeEx

before?

Thank.

+3


source to share


2 answers


Why does StringFromCLSID work even without calling CoInitializeEx before?

Key information is indicated directly in the documentation.

CoInitializeEx

function
:

You need to initialize the COM library on a thread before you call any of the library functions except ... the memory allocation functions . Otherwise, the COM function will return CO_E_NOTINITIALIZED.

StringFromCLSID

function
:



StringFromCLSID calls the StringFromGUID2 function to convert a globally unique identifier (GUID) to a printable character string.

The responder is responsible for freeing the memory allocated for the string by calling the CoTaskMemFree function .

StringFromCLSID()

returns a dynamically allocated string. We can infer from the clause highlighted above that memory is allocated with CoTaskMemAlloc()

- this is clearly documented as not requiring CoInitializeEx()

.

StringFromGUID2()

formats GUID

data into the specified memory block number. String formatting does not require COM functionality. wsprintfW()

, StringCbPrintfW()

or another function equivalent would be sufficient. Therefore CoInitializeEx()

not required for StringFromGUID2()

, although this is not explicitly documented. I think it would be rather shortsighted for Microsoft not to use one of their many available string formatting functions to implement StringFromGUID2()

. So I think it's safe to say what is CoInitializeEx()

not a prerequisite for doing this (unless Microsoft says otherwise).

The structure GUID

just contains a few numbers and bytes. The declaration and use GUID

is independent of the COM library. You are free to use GUID

in your code if you want without touching COM at all - if you don't want to generate a new one GUID

, in which case the CoInitializeEx()

requirement for is CoCreateGUID()

blurry as it CoCreateGUID()

is in the COM library, but is explicitly documented as just a call UuidCreate()

that is instead in the library RPC.

Therefore, you can call StringFromCLSID()

without calling CoInitializeEx()

. A GUID

itself does not require COM initialization. The string is allocated by a memory function that does not require COM initialization. And the string is formatted in a way that most likely doesn't require COM initialization.

+1


source


StringFromCLSID

is basically printing out the GUID value (bytes) into a string and then formatting it with a hyphen and curly braces. There is nothing else, and therefore no COM initialization is needed to successfully complete this call.



You have to do CoInitialize

/ CoInitializeEx

to be safe, but by not doing this, you don't necessarily immediately run into a problem.

+4


source







All Articles