简体   繁体   中英

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

From the wincrypt api I am receiving a void* pointing to a char*. This char* is pointing to the start of a char[]. I am also receiving a void* pointing to a int with the size of the char* .

Regarding pvData and cbData I have the following documentation from 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.

I want to convert this void* to a std::string but so far all I am getting when outputting my std::string is the first character.

I have read: Converting a void* to a std::string but since my void* is pointing to a char* instead of std::string the static_cast in the accepted answer fails and the returned std::string* triggers a null pointer exception.

So far I have the following:

// 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

I have also tried

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

If the char buffer isn't null-terminated, then to use the (void*)cbData length:

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

See the std::string constructor reference (#5, from buffer) and ::assign reference (#4, buffer).

EDIT: If you're trying to use the function CertGetCertificateContextProperty with dwPropId CERT_FRIENDLY_NAME_PROP_ID , here is how you should call the function:

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);

No dealing with void* pointers!

The documentation specifically states that it returns a Unicode string, which in Microsoft-speak means UTF-16. Characters that are part of the ASCII range will contain a zero in their second byte, which ends a string copy prematurely. You would get better results using wstring with a cast to wchar_t* .

If copying to string appears to work, it's because those zero bytes are invisible.

Putting this in the context of your original code:

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

Note that this isn't the easiest way to do it, you should also follow the advice from qxz regarding the string constructor and the passing of cbData .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM