【发布时间】:2015-05-02 23:50:47
【问题描述】:
我不确定我的实现中是否存在基本问题,或者在格式化系统错误消息方面存在 Windows API 错误。
我有一个 FormatMessage 函数的 Windows API 包装方法。我的实现允许调用者传入额外的参数以允许格式化系统错误消息。
方法签名如下:
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),我将得到以下信息(请注意,由于 @,这不会进入我发布的代码块中987654330@线):
驱动器中有错误的软盘。将 %2(卷序列号:%3)插入驱动器 %1。`
如果我将该方法称为test.setFormattedMessage(3, L"C:", L"disk 2", L"ABC123"),我会得到以下信息:
驱动器中有错误的软盘。将磁盘 2(卷序列号:ABC123)插入驱动器 C:.;
但是,对于包含 %hs 或 %08lx 等示例的错误消息,我在尝试格式化文本时遇到了问题。
以错误代码 573 为例。当将参数 0 传递给方法时,我得到以下文本(如预期的那样):
{Missing System File} 所需的系统文件 %hs 损坏或丢失。
但是,如果我传入(1, "test"),我最终会得到:
{Missing System File} 所需的系统文件 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等之外的任何内容都将被视为格式字符串。文档在哪里说它会?我认为你在这里的使命基本上是徒劳的。 -
@DavidHeffernan - msdn.microsoft.com/en-us/library/windows/desktop/… - 查找
%n!format string!- 我从这些备注/注释中假设我可以传入整数、“短字符样式”(%hs) 字符串等。 -
我根本不会这样读。
%hs不符合要求。现在,%1!hs!可能。 -
关于不支持
%hs的文档似乎没有明确说明。例如,在我提到的块之后,它引用了“百分号字符之后的任何其他非数字字符在输出消息中被格式化,没有百分号字符。以下是一些示例......”。我的观点的关键部分“......是一些例子”。 -
我没有看到任何证据表明
%hs会被格式化为hs以外的任何内容。这就是文档对我说的。
标签: c++ windows winapi visual-studio-2013 error-handling