UNICODE_STRING to wchar_t* null terminated
UNICODE_STRING to wchar_t* null terminated
我想使用UNICODE_STRING
中的缓冲区,但似乎我不能通过复制引用直接使用它,因为有时我可以看到字符串中间有空字节,Length
大于我在调试器中看到的。所以如果我这样做
UNICODE_STRING testStr;
//after being used by some function it has data like this 'bad丣 more_stuff '
wchar_t * wStr = testStr.Buffer;
我最终会得到wStr = "bad丣";
有没有办法将其转换为以空结尾的有效wchar_t*
?
wchar_t*
只是一个指针。 除非您告诉调试器(或将wchar_t*
传递给的任何函数)实际指向的wchar_t
字符数,否则它必须在某个地方停止,因此它会在遇到的第一个 null 字符处停止。
UNICODE_STRING::Buffer
不保证以 null 结尾,但它可以包含嵌入的 null。 你必须使用UNICODE_STRING::Length
字段来知道Buffer
中有多少个WCHAR
元素,包括嵌入的空值,但不计算尾随的空终止符(如果存在)。 如果需要 null 终止符,请将Buffer
数据复制到您自己的缓冲区并追加终止符。
最简单的方法是使用 std::wstring
,例如:
#include <string>
UNICODE_STRING testStr;
// fill testStr as needed...
std::wstring wStrBuf(testStr.Buffer, testStr.Length / sizeof(WCHAR));
const wchar_t *wStr = wStrBuf.c_str();
嵌入的 null 仍然存在,但c_str()
将为您追加尾随的 null 终止符。 调试器仍将仅显示第一个 null 之前的数据,除非您告诉调试器数据中WCHAR
元素的实际数量。
或者,如果您知道Buffer
数据包含多个由 null 分隔的子字符串,则可以选择将Buffer
数据拆分为字符串数组,例如:
#include <string>
#include <vector>
UNICODE_STRING testStr;
// fill testStr as needed...
std::vector<std::wstring> wStrArr;
std::wstring wStr(testStr.Buffer, testStr.Length / sizeof(WCHAR));
std::wstring::size_type startidx = 0;
do
{
std::wstring::size_type idx = wStr.find(L' ', startidx);
if (idx == std::wstring::npos)
{
if (startidx < wStr.size())
{
if (startidx > 0)
wStrArr.push_back(wStr.substr(startidx));
else
wStrArr.push_back(wStr);
}
break;
}
wStrArr.push_back(wStr.substr(startidx, idx-startidx));
startidx = idx + 1;
}
while (true);
// use wStrArr as needed...
或:
#include <vector>
#include <algorithm>
UNICODE_STRING testStr;
// fill testStr as needed...
std::vector<std::wstring> wStrArr;
WCHAR *pStart = testStr.Buffer;
WCHAR *pEnd = pStart + (testStr.Length / sizeof(WCHAR));
do
{
WCHAR *pFound = std::find(pStart, pEnd, L' ');
if (pFound == pEnd)
{
if (pStart < pEnd)
wStrArr.push_back(std::wstring(pStart, pEnd-pStart));
break;
}
wStrArr.push_back(std::wstring(pStart, pFound-pStart));
pStart = pFound + 1;
}
while (true);
// use wStrArr as needed...
UNICODE_STRING是一个结构,它存储字符数据及其长度。因此,它允许嵌入NUL字符,就像std::wstring
一样,例如。
C 样式字符串(例如 另一方面,wchar_t*
) 不存储显式字符串长度。按照惯例,它由 NUL 字符终止。它的长度是隐含的。由此推论,它不能包含嵌入的 NUL 字符。
这意味着您无法在不丢失长度信息的情况下从UNICODE_STRING
转换为wchar_t*
。您必须将长度与wchar_t*
指针一起显式存储,或者建立解释规则,以允许重新计算长度(例如,通过将字符序列解释为以双 null 结尾的字符串)1)。
附加信息:
- 没有字符串的
- 双 null 结尾字符串的格式是什么?
- 为什么使用以双 null 结尾的字符串而不是指向字符串的指针数组?
1)调试器会将
wchar_t*
解释为以零结尾的字符串。如果要查看整个序列,则需要使用格式说明符显式提供数组大小。- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 如何在 c++ 中'NULL'字符串
- c++使用foreach使数组为null
- 当使用通配符和null指针调用函数时,对输出的说明
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- 构造函数中的 QQuickItem 父项 null
- 检查字符串是否"null" C++
- fopen 在 gdb 中返回 NULL
- what(): basic_string::_M_construct null not valid
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 为什么要从main()返回NULL?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- NULL terminated c_str()?
- UNICODE_STRING to wchar_t* null terminated