MultiByteToWideChar 函数 (stringapiset.h)
将字符串映射到 UTF-16(宽字符)字符串。 字符串不一定来自多字节字符集。
语法
int MultiByteToWideChar(
[in] UINT CodePage,
[in] DWORD dwFlags,
[in] _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr,
[in] int cbMultiByte,
[out, optional] LPWSTR lpWideCharStr,
[in] int cchWideChar
);
参数
[in] CodePage
用于执行转换的代码页。 此参数可以设置为操作系统中安装或可用的任何代码页的值。 有关代码页的列表,请参阅 代码页标识符。 应用程序还可以指定下表中显示的值之一。
[in] dwFlags
指示转换类型的标志。 应用程序可以指定以下值的组合,MB_PRECOMPOSED为默认值。 MB_PRECOMPOSED和MB_COMPOSITE是相互排斥的。 无论其他标志的状态如何,都可以设置MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS。
价值 | 意义 |
---|---|
MB_COMPOSITE | 始终使用分解字符,即基字符和一个或多个非分步字符各具有不同的代码点值。 例如,Ä 由 A + }表示:拉丁文大写字母 A (U+0041) + 组合分音符 (U+0308)。 请注意,此标志不能用于MB_PRECOMPOSED。 |
MB_ERR_INVALID_CHARS | 如果遇到无效的输入字符,则失败。 从 Windows Vista 开始,如果应用程序未设置此标志,则函数不会删除非法代码点,而是将非法序列替换为 U+FFFD(根据指定的代码页进行编码)。 Windows 2000 SP4 及更高版本,Windows XP: 如果未设置此标志,该函数将无提示删除非法代码点。 GetLastError 调用将返回ERROR_NO_UNICODE_TRANSLATION。 |
- MB_PRECOMPOSED
- MB_USEGLYPHCHARS
对于下面列出的代码页,dwFlags 必须设置为 0
。 否则,函数将失败并 ERROR_INVALID_FLAGS。
- 50220
- 50221
- 50222
- 50225
- 50227
- 50229
- 57002 到 57011
- 65000 (UTF-7)
- 42 (符号)
注意
对于 UTF-8 或代码页 54936(GB18030,从 Windows Vista 开始),dwFlags 必须设置为 0
或 MB_ERR_INVALID_CHARS。 否则,函数将失败并 ERROR_INVALID_FLAGS。
[in] lpMultiByteStr
指向要转换的字符串的指针。
[in] cbMultiByte
lpMultiByteStr 参数指示的字符串的大小(以字节为单位)。 或者,如果字符串以 null 结尾,则可以将此参数设置为 -1。 请注意,如果 cbMultiByte0
,则函数将失败。
如果此参数为 -1,则该函数将处理整个输入字符串,包括终止 null 字符。 因此,生成的 Unicode 字符串具有终止 null 字符,函数返回的长度包括此字符。
如果此参数设置为正整数,则函数将完全处理指定的字节数。 如果提供的大小不包括终止 null 字符,则生成的 Unicode 字符串不会以 null 结尾,并且返回的长度不包括此字符。
[out, optional] lpWideCharStr
指向接收转换后的字符串的缓冲区的指针。
[in] cchWideChar
lpWideCharStr指示的缓冲区的大小(以字符为单位)。 如果此值 0
,则该函数将返回所需的缓冲区大小(以字符为单位,包括任何终止 null 字符)并且不使用 lpWideCharStr 缓冲区。
返回值
返回写入缓冲区的字符数,lpWideCharStr(如果成功)。 如果函数成功,cchWideChar 为 0
,则返回值是 lpWideCharStr指示的缓冲区所需的大小(以字符为单位)。 另请参阅 dwFlags,了解输入无效序列时 MB_ERR_INVALID_CHARS 标志如何影响返回值的信息。
如果函数不成功,则返回 0
。 若要获取扩展的错误信息,应用程序可以调用 GetLastError,这会返回以下错误代码之一:
-
ERROR_INSUFFICIENT_BUFFER:提供的缓冲区大小不够大,或者错误地设置为
NULL
。 - ERROR_INVALID_FLAGS:为标志提供的值无效。
- ERROR_INVALID_PARAMETER:任何参数值都无效。
- ERROR_NO_UNICODE_TRANSLATION:在字符串中找到无效的 Unicode。
言论
此函数的默认行为是转换为输入字符串的预编译形式。 如果预编译的窗体不存在,该函数将尝试转换为复合窗体。
MB_PRECOMPOSED标志的使用对大多数代码页的影响很小,因为大多数输入数据已经组成。 请考虑使用 MultiByteToWideChar转换后调用 NormalizeString。 NormalizeString 提供更准确的、标准和一致的数据,而且速度更快。 请注意,对于传递给 NormalizeString的 NORM_FORM 枚举,NormalizationC 对应于MB_PRECOMPOSED,NormalizationD 对应于MB_COMPOSITE。
如上述警告中所述,如果未首先调用此函数,则输出缓冲区很容易被过度运行,cchWideChar 设置为 0
以获取所需的大小。 如果使用MB_COMPOSITE标志,则每个输入字符的输出长度可以为三个或更多个字符。
lpMultiByteStr 和 lpWideCharStr 指针不得相同。 如果相同,函数将失败,GetLastError 返回值ERROR_INVALID_PARAMETER。
MultiByteToWideChar 如果未显式指定输入字符串长度而不终止 null 字符,则不会终止输出字符串。 若要为 null 终止此函数的输出字符串,应用程序应传入 -1 或显式计算输入字符串的终止 null 字符。
如果设置了MB_ERR_INVALID_CHARS,并且源字符串中遇到无效字符,则函数将失败。 无效字符为下列字符之一:
- 不是源字符串中的默认字符的字符,但在未设置MB_ERR_INVALID_CHARS时转换为默认字符。
- 对于 DBCS 字符串,该字符具有前导字节,但没有有效的尾随字节。
从 Windows Vista 开始,此函数完全符合 UTF-8 和 UTF-16 的 Unicode 4.1 规范。 在早期操作系统上使用的函数对 代理项 一半或不匹配的代理项对进行编码或解码。 在早期版本的 Windows 中编写的代码,依赖于此行为来编码随机的非文本二进制数据可能会遇到问题。 但是,对有效 UTF-8 字符串使用此函数的代码的行为方式与早期 Windows 操作系统相同。
Windows XP: 为防止 UTF-8 字符的非最短格式版本的安全问题,MultiByteToWideChar 删除这些字符。
从 Windows 8 开始 :MultiByteToWideChar 在 Stringapiset.h
中声明。 在 Windows 8 之前,它在 Winnls.h
中声明。
代码示例
catch (std::exception e)
{
// Save in-memory logging buffer to a log file on error.
::std::wstring wideWhat;
if (e.what() != nullptr)
{
int convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), NULL, 0);
if (convertResult <= 0)
{
wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
wideWhat += convertResult.ToString()->Data();
wideWhat += L" GetLastError()=";
wideWhat += GetLastError().ToString()->Data();
}
else
{
wideWhat.resize(convertResult + 10);
convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), &wideWhat[0], (int)wideWhat.size());
if (convertResult <= 0)
{
wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
wideWhat += convertResult.ToString()->Data();
wideWhat += L" GetLastError()=";
wideWhat += GetLastError().ToString()->Data();
}
else
{
wideWhat.insert(0, L"Exception occurred: ");
}
}
}
else
{
wideWhat = L"Exception occurred: Unknown.";
}
Platform::String^ errorMessage = ref new Platform::String(wideWhat.c_str());
// The session added the channel at level Warning. Log the message at
// level Error which is above (more critical than) Warning, which
// means it will actually get logged.
_channel->LogMessage(errorMessage, LoggingLevel::Error);
SaveLogInMemoryToFileAsync().then([=](StorageFile^ logFile) {
_logFileGeneratedCount++;
StatusChanged(this, ref new LoggingScenarioEventArgs(LoggingScenarioEventType::LogFileGenerated, logFile->Path->Data()));
}).wait();
}
GitHub 上 Windows 通用示例 的示例。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows 2000 Professional [桌面应用 |UWP 应用] |
支持的最低服务器 | Windows 2000 Server [桌面应用 |UWP 应用] |
目标平台 | 窗户 |
标头 | stringapiset.h (包括 Windows.h) |
库 | Kernel32.lib |
DLL | Kernel32.dll |
另请参阅
VBS enclave 中提供的 Vertdll API