Получение char* из _variant_t в оптимальное время
Вот код, который я хочу ускорить. Он получает значение из набора записей ADO и преобразует его в символ *. Но это медленно. Могу ли я пропустить создание _bstr_t?
_variant_t var = pRs->Fields->GetItem(i)->GetValue();
if (V_VT(&var) == VT_BSTR)
{
char* p = (const char*) (_bstr_t) var;
5 ответов
Первые 4 байта BSTR содержат длину. Вы можете перебрать и получить любой другой символ, если используется юникод, или каждый символ, если многобайтовый. Какой-нибудь memcpy или другой метод тоже подойдет. IIRC, это может быть быстрее, чем W2A
или кастинг (LPCSTR)(_bstr_t)
Ваша проблема (кроме возможности копирования памяти внутри _bstr_t) заключается в том, что вы конвертируете UNICODE BSTR в символ ANSI *.
Вы можете использовать макросы USES_CONVERSION, которые выполняют преобразование в стеке, поэтому они могут быть быстрее. В качестве альтернативы, сохраните значение BSTR как Unicode, если это возможно.
преобразовать:
USES_CONVERSION;
char* p = strdup(OLE2A(var.bstrVal));
// ...
free(p);
запомните - строка, возвращаемая из OLE2A (и его сестринских макросов), возвращает строку, расположенную в стеке, - возвращайте из охватывающей области видимости, и у вас будет строка мусора, если вы не скопируете ее (и, в конце концов, освободите ее, очевидно)
Это создает временное в стеке:
USES_CONVERSION;
char *p=W2A(var.bstrVal);
Это использует немного более новый синтаксис и, вероятно, более устойчивый. Он имеет настраиваемый размер, после которого он будет использовать кучу, чтобы избежать размещения массивных строк в стеке:
char *p=CW2AEX<>(var.bstrVal);
_variant_t var = pRs->Fields->GetItem(i)->GetValue();
Вы также можете сделать это назначение быстрее, избегая совокупности полей. Вы должны использовать коллекцию Fields только тогда, когда вам нужно получить элемент по имени. Если вы знаете поля по индексу, вы можете использовать это.
_variant_t vara = pRs->Collect[i]->Value;
Обратите внимание, что я не могу быть целым числом, так как ADO не поддерживает VT_INTEGER, поэтому вы можете также использовать длинную переменную.
Хорошо, мой C++ становится немного ржавым... но я не думаю, что преобразование - ваша проблема. Это преобразование ничего не делает, кроме как сказать компилятору считать _bstr_t символом *. Тогда вы просто назначаете адрес этого указателя на p. На самом деле ничего не делается.
Вы уверены, что это не просто медленно получать вещи из GetValue?
Или мой C++ более грубый, чем я думаю...