我使用
CreateProcessW
函数创建了一个子进程,该函数的管道作为其自身与其父进程之间的 STDOUT 和 STDIN 。我无法使用 WriteFile
和 ReadFile
函数以宽字符形式发送和获取数据。
我不知道为管道设置 std::locale 。有没有一种方法可以专门告诉这些管道将数据编码为 UTF-16 中的宽字符,类似于 ifstreams 和 ofstreams?
谢谢。
你在这里:
static wchar_t buffer [sz];
int WriteToPipe(const std::wstring& str)
{
int result = WriteFile(PipeStdin, (LPVOID)str.c_str(), str.size(), &bytesWritten, NULL);
_assert(str.size()==bytesWritten);
return result;
}
// simply turns back what was on its stdin
wchar_t* ReadFromPipe()
{
ReadFile(PipeStdout, (LPVOID)buffer, sz, &bytesRead, NULL);
return buffer;
}
void Test()
{
std::wstring test { L"test" };
WriteToPipe (test);
wchar_t* ret = ReadFromPipe (); // gets back 't' when using std::wcout
}
它只得到“t”,显然是因为缓冲区是 t e s t 。
如果管道的默认编码是UTF-8,那就有意义,否则我必须找出那里在做什么。如果我可以设置管道将缓冲区视为 UTF-16,那就太好了。
WriteFile 需要写入的字节数,而不是字符数。
当我用
str.size ()
替换 sizeof (wchar_t) * str.size ()
时,整个字符串就会被写入然后读出。至少当我使用带有默认参数的普通 CreatePipe 调用创建管道时。
还要确保在传递到 wprint 或 wout 之前以 NUL 终止它。
解决方案:
我在“预处理器定义”中进行了两项更改,即添加可用的 _UNICODE 和 _MBCS 宏,并为 std::wcin 添加 UTF-16 模式,如下所示:
const unsigned long MaxCode = 0x10FFFF;
const std::codecvt_mode Mode = (std::codecvt_mode)(std::generate_header | std::little_endian);
std::locale utf16_locale(std::wcin.getloc(), new std::codecvt_utf16<wchar_t, MaxCode, Mode>);
std::wcin.imbue (utf16_locale);