2016-08-21 2 views
-1

Из wincrypt api я получаю пустоту *, указывающую на char *. Этот символ * указывает на начало символа char []. Я также получаю void*, указывающий на int с размером char*.преобразование void * указание на char * на std :: string в C++

Относительно pvData и cbData У меня есть следующая документация от Microsoft.

Тип данных pvData: указатель на массив значений BYTE. Размер этого массива указан в параметре cbData. Возвращает строку символов Unicode с нулевым символом, которая содержит отображаемое имя для сертификата.

Я хочу, чтобы преобразовать это void* к std::string, но до сих пор все, что я получаю при выводе мой std::string является первым символом.

Я прочитал: Converting a void* to a std::string, но так как мой void* указывает на char* вместо std::stringstatic_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

Проверьте аргументы, переданные в 'std :: string :: assign'. – juanchopanza

+1

* "Этот char \ * является символом char []" * Что это значит? –

+1

И если вы выбрали int * для int, у вас есть UB (или неожиданное значение, в лучшем случае). Это * cbData –

ответ

5

Если буфер символ не оканчивается нулем, то использовать (void*)cbData длина:

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

См. std::stringconstructor reference (# 5, from buffe r) и ::assign reference (№4, буфер).

EDIT: Если вы пытаетесь использовать функцию CertGetCertificateContextProperty с dwPropIdCERT_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* указателей!

+0

Добрый сэр, вы выиграли интернет на сегодня, я был близок, но не сигал. причиной этого стала передача int прямо в std :: string :: assign вместо того, чтобы сделать его size_t! – Corne

+1

@Corne Я думаю, проблема заключалась в том, что вы вводили 'void *' в 'int', когда вы должны были передать его в' int * '. – Galik

+0

@Galik нет, это была опечатка, которую я удалил, чтобы избежать путаницы, извините за это ~! – Corne

2

В документации конкретно указывается, что она возвращает строку Юникод, которая в Microsoft-talk означает 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.

+0

Я также заметил это в своем выпуске, потому что между каждым персонажем есть пробел. Это объясняет, почему копирование при указании size_t заставляет его работать. я обязательно перейду к переменным Unicode, как описано. – Corne

Смежные вопросы