在 C++ 中将指向 char* 的 void* 转换为 std::string

converting void* pointing to char* to a std::string in c++

从 wincrypt api 我收到一个指向 char* 的 void*。 这个 char* 指向 char[] 的开始。我还收到一个 void* 指向一个大小为 char*.

的 int

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

Data type of pvData: A pointer to an array of BYTE values. The size of this array is specified in the cbData parameter. Returns a null-terminated Unicode character string that contains the display name for the certificate.

我想将此 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

如果 char 缓冲区不是空终止的,则使用 (void*)cbData 长度:

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

参见 std::string constructor reference (#5, from buffer) and ::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* 指针!

文档明确指出它 returns 一个 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());

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

的传递