Reputation: 141
i would like to have your opinion about this wrapper for LoadString Win32 function.
int LoadWString( HINSTANCE hInstance_In, UINT uID_In, std::wstring &str_Out ){
return LoadStringW( hInstance_In, uID_In, (LPWSTR)str_Out.c_str(), (int)str_Out.max_size());
}
as it seems to work as expected, question is more about using strings max_size property as buffer size, does this have some negative drawbacks?
Upvotes: 0
Views: 1935
Reputation: 51345
c_str()
returns a non-modifiable pointer. It must not be written to. Casting away const-ness and writing to the controlled sequence results in undefined behavior.
Instead, simply query for a pointer into the resource section, together with the string length, and construct a new std::wstring
object on this data:
std::wstring LoadStringW( unsigned int id )
{
const wchar_t* p = nullptr;
int len = ::LoadStringW( nullptr, id, reinterpret_cast<LPWSTR>( &p ), 0 );
if ( len > 0 )
{
return std::wstring{ p, static_cast<size_t>( len ) };
}
// Return empty string; optionally replace with throwing an exception.
return std::wstring{};
}
There are a few points worth noting:
0
for nBufferMax. Doing so returns a pointer into the resource section; no additional memory allocation is performed:nBufferMax:
If this parameter is 0, then lpBuffer receives a read-only pointer to the resource itself.
NUL
characters. This mandates the use of a std::string constructor taking an explicit length argument. return std::wstring(p);
would potentially truncate the returned string.Upvotes: 8