Why does this work (COM & strings)?

I'm messing around with MS text to speech and wrote some code to iterate through voice attributes stored in the registry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ~ 50 lines removed for brevity

ISpObjectToken* token = NULL;
ISpDataKey* key = NULL;
LPWSTR keyname = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * 256);
LPWSTR valname = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * 256);
LPWSTR val = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * 2048);

//*get a token*

//*open attributes key*

ULONG valid=0;
while(key->EnumValues(valid, &valname) == S_OK){

	key->GetStringValue(valname, &val);
	std::wcout << keyname << L":" << valname << L" = "<<val<<L"\n";
	
	valid++;
}


My question is this:

strings holding these names and values are allocated once, never initialized, and never modified outside of API calls.
MSDN calls for an "address of a pointer to a null-terminated string" in the case of &val

How do these functions know the size of the buffer I'm passing?

For example, say we first read the gender attribute of a voice. val now holds "Male\0". Why doesn't the subsequent call querying the name -"Microsoft David" - fail due to apparently insufficient buffer size (i.e. wcslen(val) returning 4)?

If CoTaskMemAlloc stores the size internally, why does it need to be passed for ISpDataKey::GetData (essentially the same as GetStringValue, just writing to a BYTE* buffer instead of LPWSTR* and requiring a size parameter)?


Edited to include links to documentation:

https://msdn.microsoft.com/en-us/library/ms717835(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/ms717833(v=vs.85).aspx
Last edited on
When a function asks for a pointer to a pointer it is a sign that the function wants to modify the pointer. I think the string data that val is pointing to before you pass it to GetStringValue is left unchanged but instead val will be set to point to a different string.
Thanks Peter87, you are correct. I should've thought of that
Topic archived. No new replies allowed.