Получение char * из _variant_t в оптимальное время - PullRequest
4 голосов
/ 23 сентября 2008

Вот код, который я хочу ускорить. Он получает значение из набора записей 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 ]

3 голосов
/ 23 сентября 2008

Первые 4 байта BSTR содержат длину. Вы можете перебрать и получить любой другой символ, если используется юникод, или каждый символ, если многобайтовый Какой-нибудь memcpy или другой метод тоже подойдет. IIRC, это может быть быстрее, чем W2A или кастинг (LPCSTR)(_bstr_t)

3 голосов
/ 23 сентября 2008

Ваша проблема (кроме возможности копирования памяти внутри _bstr_t) заключается в том, что вы конвертируете UNICODE BSTR в символ ANSI *.

Вы можете использовать макросы USES_CONVERSION, которые выполняют преобразование в стеке, поэтому они могут быть быстрее. В качестве альтернативы, если возможно, сохраните значение BSTR в Юникоде.

конвертировать:

USES_CONVERSION;
char* p = strdup(OLE2A(var.bstrVal));

// ...

free(p);

запомните - строка, возвращаемая из OLE2A (и его сестринских макросов), возвращает строку, выделенную в стеке, - возвращайтесь из окружающей области видимости, и у вас есть строка мусора, если вы не скопируете ее (и, в конце концов, освободите ее, очевидно) * *

2 голосов
/ 23 сентября 2008

Это создает временный файл в стеке:

USES_CONVERSION;
char *p=W2A(var.bstrVal);

Это использует немного более новый синтаксис и, вероятно, более устойчивый. Он имеет настраиваемый размер, после которого он будет использовать кучу, чтобы избежать размещения массивных строк в стеке:

char *p=CW2AEX<>(var.bstrVal);
0 голосов
/ 04 марта 2010
_variant_t var = pRs->Fields->GetItem(i)->GetValue(); 

Вы также можете сделать это назначение быстрее, избегая совокупности полей. Вы должны использовать коллекцию Fields только тогда, когда вам нужно получить элемент по имени. Если вы знаете поля по индексу, вы можете использовать это.

_variant_t vara = pRs->Collect[i]->Value;

Обратите внимание, что я не могу быть целым числом, поскольку ADO не поддерживает VT_INTEGER, поэтому вы также можете использовать длинную переменную.

0 голосов
/ 23 сентября 2008

Хорошо, мой C ++ становится немного ржавым ... но я не думаю, что преобразование - ваша проблема. Это преобразование ничего не делает, кроме как сказать компилятору считать _bstr_t символом *. Тогда вы просто назначаете адрес этого указателя на p. На самом деле ничего не делается ". 1001 *

Вы уверены, что получить GetValue не просто медленно?

Или мой C ++ более грубый, чем я думаю ...

...