I am learning COM through C++. From MSDN:
Applications are required to use CoInitializeEx before they make any other COM library calls except for memory allocation functions.
The memory allocation functions is CoTaskMemAlloc
and CoTaskMemFree
in my opinion.
But I see, my "Hello World" works fine with and without the CoInitializeEx
and CoUninitialize
functions calling. In my code I use the StringFromCLSID
function which is declared in the combaseapi.h
header. So, it 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 calls of CoInitializeEx
and CoUninitialize
functions, then my code works still. I expected it will not work...
Why StringFromCLSID
work even without the calling of CoInitializeEx
before?
Thank you.
StringFromCLSID
is basically a printout of GUID value (bytes) into string, then formatting it nicely with hyphens and braces. There is nothing else involved and hence COM initialization is not really needed for this call to succeed.
You have to do CoInitialize
/CoInitializeEx
to be safe, but not doing it you don't necessarily hit a problem right away.
Why StringFromCLSID work even without the calling of CoInitializeEx before?
The key information is stated right 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) into a string of printable characters.
The caller 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 highlighted sentence above that the memory is allocated using CoTaskMemAlloc()
- which is explicitly documentated as not requiring CoInitializeEx()
.
StringFromGUID2()
formats GUID
data into a caller-specified memory block. Formatting a string does not require COM functionality. The wsprintfW()
, StringCbPrintfW()
, or other equivalent function would suffice. So CoInitializeEx()
should not be required for StringFromGUID2()
, even though this is not explicitly documented. I think it would be pretty short-sighted for Microsoft to not use one of their many available string formatting functions to implement StringFromGUID2()
. So I think it should be safe to say that CoInitializeEx()
is not a requirement for this (unless Microsoft says otherwise).
The GUID
structure simply contains a few numbers and bytes. Declaring and using a GUID
is not dependent on the COM library. You can freely use a GUID
in your code all you want without touching COM at all - unless you want to generate a new GUID
, in which case the CoInitializeEx()
requirement for CoCreateGUID()
is blurry as CoCreateGUID()
is in the COM library but is explicitly documented as simply calling UuidCreate()
, which is in the RPC library instead.
So that is why you can call StringFromCLSID()
without calling CoInitializeEx()
first. A GUID
on its own does not require COM initialization. The string is being allocated with a memory function that does not require COM initialization. And the string is being formatted in a manner that most likely does not require COM initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With