我不確定是否在執行過程中遇到了根本性問題,或者在Windows API中存在與格式化系統錯誤消息有關的錯誤。如何使用FormatMessage函數填充系統錯誤消息的va_list?
我有一個Windows API包裝方法的FormatMessage
函數。我的實現允許調用者傳入附加參數以允許系統錯誤消息的格式化。
方法簽名如下:
bool setFormattedMessage(int arguments, ...)
在這個方法中我有下面的代碼塊不會出現爲我所有的單元測試工作:
if (arguments)
{
va_list argumentsList;
va_start(argumentsList, arguments);
size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, language, (LPWSTR)&buffer, 0,
&argumentsList);
va_end(argumentsList);
}
注意: code
和language
是在實例化列表中設置的類的成員(使用GetLastError
和LANGIDFROMLCID(GetThreadLocale())
。
這裏有一些單元測試通過,沒有任何問題:
如果我創建類的實例爲34的錯誤代碼,我會得到下面的,如果我調用該方法爲test.setFormattedMessage(0)
(注意,這沒有按」 t進入由於if (arguments)
線而發佈的代碼塊):
錯誤的軟盤在驅動器中。插入%2(卷序列號:%3)插入驅動器%1.`
如果我調用方法test.setFormattedMessage(3, L"C:", L"disk 2", L"ABC123")
我得到如下:
錯誤的軟盤驅動器中。將磁盤2(卷序列號:ABC123)插入驅動器C:。
然而,對於包括這樣的例子作爲%hs
%08lx
或我碰上試圖格式化文本的問題的錯誤消息。
採取的錯誤代碼573的例子當傳遞參數0到我得到了下面的文字(如預期)的方法:
{丟失的系統文件}所需的系統文件%HS是壞或失蹤。
但是,如果我通過在(1, "test")
我結束了:
{丟失的系統文件}所需的系統文件HS是損壞或丟失。
事實上,我已經發現,不管是否我傳遞"test"
,L"test"
,的char
,wchar_t
等副本我總是與上述錯誤信息而告終。創建的消息與傳遞(0)
相同,但將%
從字符串中刪除。
我發現所有其他參數的相同問題,除非它們被編號(例如%1
)。我完全停留在這一點上,以至於我是否犯了根本性錯誤,或者在FormatMessage
函數中確實存在缺陷。
我是,我可以在更換傳爲%hs
佔位符以同樣的方式下的印象,我會做它swprintf
:
char * t = "file 123";
wchar_t a[2000];
int v = swprintf(a, 2000, L"Blah blah %hs", t);
std::wstring someText(a, v);
等等等等文件123
我看不到有任何證據表明超出'%1','%2'等任何內容都將被視爲格式字符串。文檔在哪裏說它會?我認爲你在這裏的任務基本上是徒勞的。 – 2015-03-02 15:15:12
@DavidHeffernan - https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx - 查找'%n!格式字符串!' - 我從這些評論中推斷出/筆記,我可以通過整數,「短字符風格」('%hs')字符串等。 – camelCase 2015-03-02 16:01:18
我不會那樣讀。 '%hs'不符合法案。現在,'%1!hs!'可能會。 – 2015-03-02 16:08:15