2015-10-25 34 views
0

我想有關於這個包裝的LoadString Win32函數的意見。C++,Win32的LoadString包裝

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()); 
} 

,因爲它似乎按預期方式工作,問題更多的是使用字符串max_size個屬性作爲緩衝區的大小,這確實有一些負面的缺點?

+0

這是未定義的行爲,ergo,你不能依靠它的工作。一方面,字符串將不知道它現在包含有效數據或該字符串有多長。使用臨時緩衝區和'str_Out.assign()'。 –

回答

4

c_str()返回一個不可修改的指針。它不能寫入。丟棄常量並寫入受控序列導致未定義的行爲

相反,簡單地用字符串長度查詢指針到資源部分,同時,建設這個數據的新std::wstring對象:

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(); 
} 

有值得注意的幾點:

  • 執行使用LoadString,通過0nBufferMax。這樣做會返回一個指向資源部分的指針;不執行任何額外的內存分配:

    nBufferMax
    如果該參數爲0,則lpBuffer接收只讀指針資源本身。

  • 字符串資源是計數的字符串,並且可以包含嵌入的NUL字符。這要求使用具有明確長度參數的std::string constructorreturn std::wstring(p);可能會截斷返回的字符串。
  • 由於layout of string resources,通常無法判斷任何給定ID的字符串資源是否爲空或不存在。這個答案中的實現遵循如下規則:如果字符串資源爲空或者不存在,則返回空字符串。
+0

祝賀10K btw! –

+0

@JonathanPotter:非常感謝! – IInspectable