【问题标题】:converting void* pointing to char* to a std::string in c++将指向 char* 的 void* 转换为 c++ 中的 std::string
【发布时间】:2016-12-28 08:24:07
【问题描述】:

从 wincrypt api 我收到一个指向 char* 的 void*。 此 char* 指向 char[] 的开头。我还收到了一个void* 指向一个大小为char* 的int。

关于 pvData 和 cbData 我有以下来自 Microsoft 的文档。

pvData 的数据类型:指向 BYTE 值数组的指针。此数组的大小在 cbData 参数中指定。返回一个以 null 结尾的 Unicode 字符串,其中包含证书的显示名称。

我想将此void* 转换为std::string,但到目前为止,我在输出std::string 时得到的只是第一个字符。

我已阅读:Converting a void* to a std::string,但由于我的void* 指向char* 而不是std::string,因此接受的答案中的static_cast 失败,返回的std::string* 触发空指针异常。

到目前为止,我有以下内容:

// pvData = void* pointing to char*
// cbData = void* pointing to int*
std::string tempName;
tempName.assign(static_cast<char*>(pvData), static_cast<int*>(cbData));
printf("%S \n", pvData); // entire string is shown
printf("%s \n", tempName.c_str()); // only first character is shown

我也试过

tempName = static_cast<char*>(pvData); // only single character returned

tempName.assign(static_cast<char*>(pvData)); // only single character returned

char* arr = static_cast<char*>(pvData);
std::string tempName(arr); // only single character returned empty with printf must 
// use std::cout

【问题讨论】:

  • 检查传递给std::string::assign的参数。
  • "This char* is a char[]" 这到底是什么意思?
  • 如果你将 int* 转换为 int 你有 UB(或者一个意外的值,充其量)。它是 *cbData
  • 去白板写100遍:“数组不是指针,指针也不是数组”。
  • “我还收到一个指向 int 的 void*...” - 然后你需要将其转换为 int* 而不是 int

标签: c++ string void-pointers


【解决方案1】:

如果 char 缓冲区不是以 null 结尾的,则使用 (void*)cbData 长度:

char* data = static_cast<char*>(pvData);
size_t len = *static_cast<int*>(cbData);
std::string tempName(data, len);

参见std::stringconstructor reference(#5,来自缓冲区)和::assign reference(#4,缓冲区)。

编辑:如果您尝试将函数 CertGetCertificateContextPropertydwPropId CERT_FRIENDLY_NAME_PROP_ID 一起使用,那么您应该如何调用该函数:

CERT_CONTEXT ctx;
BYTE buf[100];
DWORD len = 100;
CertGetCertificateContextProperty(&ctx, CERT_FRIENDLY_NAME_PROP_ID, buf, &len);
std::string tempName(reinterpret_cast<char*>(buf), len);

不处理void* 指针!

【讨论】:

  • 尊敬的先生,您今天赢得了互联网,我很接近但没有 sigar。将 int 直接传递给 std::string::assign 而不是将其设为 size_t 是问题的原因!
  • @Corne 我认为问题在于您将void* 转换为int,而您应该将其转换为int*
  • @Galik 不,这是一个错字,我已将其删除以避免混淆,对此感到抱歉~!
  • @Corne 看看我的编辑——这是你想要做的吗?
  • np。对于采用void* 的 WinAPI 函数(或其他 API 函数),您通常应该只向它们传递所需类型的普通指针(-to-buffer)。
【解决方案2】:

文档特别声明它返回一个 Unicode 字符串,在 Microsoft 中表示 UTF-16。属于 ASCII 范围的字符将在其第二个字节中包含一个零,这会提前结束字符串副本。使用 wstring 并转换为 wchar_t* 会获得更好的结果。

如果复制到字符串似乎有效,那是因为那些零字节是不可见的。

将其放在原始代码的上下文中:

std::wstring tempName;
tempName.assign(static_cast<wchar_t*>(pvData), (*static_cast<int*>(cbData)) / sizeof(wchar_t));
printf("%S \n", tempName.c_str());

请注意,这不是最简单的方法,您还应该遵循advice from qxz 关于字符串构造函数和cbData 的传递。

【讨论】:

  • 我在输出中也注意到了这一点,因为现在每个字符之间都有一个空格。这解释了为什么在指定 size_t 时进行复制使其工作。我一定会按照说明切换到 Unicode 变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 2010-11-14
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多