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

时间:2016-08-21 20:13:15

标签: c++ string void-pointers

从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

2 个答案:

答案 0 :(得分:5)

如果char缓冲区没有以null结尾,那么使用(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,来自缓冲区)和::assign reference(#4,缓冲区)。

编辑:如果您尝试将CertGetCertificateContextProperty功能与dwPropId 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*指针!

答案 1 :(得分: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的传递。