我正在编写一个应用程序,它通过 Windows RPC 机制与另一个进程中的托管接口进行通信。
编组是通过标准的内置 NDR 处理的。该接口公开了几个函数,其中一个UNICODE_STRING
通过参数返回字符串 ( )。
该函数在成功时返回 0,否则返回错误代码。现在,当我调用 RPC 函数时,它成功并填充了 UNICODE_STRING 参数。
问题是 C++ 或运行时在尝试读取函数返回的字符串时吞下了一个错误。为了节省您阅读大量代码,这是我的代码的缩写版本:
void func()
{
UNICODE_STRING unicode_str;
HMODULE hLib = LoadLibrary(L"Ntdll.dll");
RtlInitUnicodeStringFn fn;
fn = (RtlInitUnicodeStringFn) GetProcAddress(hLib, "RtlInitUnicodeString");
fn(&unicode_str, NULL);
std::cout << "Before calling RPC the buffer was pointing at: " << std::hex << unicode_str.Buffer << std::endl;
if(call(binding.get_binding_handle(), &unicode_str))
{
std::cout << "len: " << unicode_str.Length << " maxlen: " << unicode_str.MaximumLength << std::endl;
std::cout << "After calling RPC the buffer is pointing at: " << std::hex << unicode_str.Buffer << std::endl;
try
{
for(int i = 0; i < unicode_str.Length; i++)
std::wcout << i << ": " << unicode_str.Buffer[i] << std::endl;
}
catch(...)
{
std::cout << "Caught an exception";
}
std::wcout << "I won't be written" << std::endl;
}
}
bool call(void* handle, PUNICODE_STRING str)
{
__try
{
std::cout << "RPC call returned: " << RpcInterfaceFunction(handle, str) << std::endl;
return true;
}
__except(1)
{
std::cout << "Error: " << std::dec << GetExceptionCode() << std::endl;
return false;
}
}
执行此代码后,输出为:
Before calling RPC the buffer is pointing at : 000000000
RPC call returned: 0
len:68, maxlen: 70
After calling RPC the buffer is pointing at: 00746168
0: #
1: t
2:
并返回。我已经通过这个函数使用了一个调试器,它正确地遍历了整个 68 个字符(不管缓冲区中有什么 - 它是垃圾数据)并正确地进入最后一个I won't be written
wcout 指令。我想知道问题是否与控制台无法处理的不可读字符有关,这些字符可能会改变下一个字符的行为或控制台光标 - 这会使输出不可见,但不是 - 我已经交换了输出流并设置它到一个文件 (wofstream) 并且文件的大小是 47 字节 - 这与写入控制台流的大小完全相同。
我没有遇到任何访问冲突、任何异常、任何日志条目,什么都没有。即使调试器(VS2010)在选择中断每种可能的异常类型后也没有注意到任何异常 - 更令人惊讶的是,使用调试器单步执行代码并观察那里的本地人会产生预期值(我从 0到 68 并且缓冲区中的当前 wchar_t 有一个值(垃圾 unicode char)。
有人可以解释这种行为吗?
编辑:
交换打印循环:
for(int i = 0; i < unicode_str.Length; i++)
{
std::wcout << "I'm writing the " << i << "th character" << std::endl;
unsigned short temp = unicode_str.Buffer[i];
std::wcout << i << ": " << temp << std::endl;
}
正确打印temp
67 的值。
但是,为什么打印这些字符的 wchar_t 版本会阻止输出流接受任何内容?