_bstr_t --> C string [C++ COM]

Ventalf

Есть какой нибудь стандартный и надёжный способ преоброзовать _bstr_t в std::wstring или же в стандартный сишный массив wchar_t с ноликом в конце?

agent007new

 _bstr_t bstrWrapper;
std::wstring(static_cast<wchar_t*>(bstrWrapper bstrWrapper.length;

Dasar

_bstr_t в std::wstring или же в стандартный сишный массив wchar_t с
bstr - это и есть wchar, но с двумя отличиями
внутри bstr-строки - могут встречать символы с кодом 0, а не только как концевой
перед bstr (по смещений -4/-8) - лежит длина строки.
поэтому const bstr можно просто скастить в const wchar, при этом понимая, что в wchar может попасть лишь кусок строки, если внутри bstr-строки были нули.

Ventalf

_bstr_t bstrWrapper;
std::wstring(static_cast<wchar_t*>(bstrWrapper bstrWrapper.length;
В _bstr_t есть перегруженный оператор (wchar_t *).

Ventalf

поэтому const bstr можно просто скастить в const wchar, при этом понимая, что в wchar может попасть лишь кусок строки, если внутри bstr-строки были нули.
я так и делал но без каста

std::wstring GetItemString( const wchar_t * fieldName ) // get item by field name
{
_bstr_t tmp = this->recordsetPtr->GetFields->Item[fieldName]->Value;

return std::wstring(tmp);
}
......
std::wcout<<adors.GetItemString(L"name")<<L"\n";

Но этот способ иногда глючит видимо по тем причинам которые ты указал, нужно что-то с этим делать.

Dasar

return std::wstring(tmp);
надо смотреть исходный код этой функции.
если внутри этой функции - строка не копируется, то твой кусок целиком неверный, тк. функция возвращает указатель на строку, которая удаляется.

Serab

какой функции? это конструирование объекта, это должно работать правильно.
Ну т.е. уж наверное std::wstring копирует строку в свой внутренний буфер, как еще?

agent007new


_bstr_t bstrWrapper;
std::wstring(static_cast<wchar_t*>(bstrWrapper bstrWrapper.length;
В _bstr_t есть перегруженный оператор (wchar_t *).
Не поверишь, static_cast в данном случае - явный вызов этого оператора

Dasar

какой функции? это конструирование объекта, это должно работать правильно.
конструктор объекта - это функция. и эта функция(конструктор) может копировать строку, а может не копировать.

Serab

Ну это не просто конструктор какого-то объекта, это wstring. Ты смотришь в конструктор vector, чтобы посмотреть, выделяет он память или нет?

Dasar

Ну это не просто конструктор какого-то объекта, это wstring. Ты смотришь в конструктор vector, чтобы посмотреть, выделяет он память или нет?
лучше посмотреть, потому что C++-либы (даже stl) часто могут удивить по этому поводу.

Ventalf

если внутри этой функции - строка не копируется, то твой кусок целиком неверный, тк. функция возвращает указатель на строку, которая удаляется.
std::wstring это стандартный проверенный класс, такой проблемы тут точно нету.
Проблема в том, что иногда в _bstr_t из базы данных попадают какие-то странные символы вместе с текстом которые wstring и wcout не воспринимает и глючно на них реагируют.

agent007new

надо смотреть исходный код этой функции.
если внутри этой функции - строка не копируется, то твой кусок целиком неверный, тк. функция возвращает указатель на строку, которая удаляется.
Это ты слишком параноишь:
points at the first element of an allocated COPY of the array whose first element is pointed at by s

А по делу, если в строке будет что-нить не из ASCII-набора (например, русские буквы то вывод будет неправильный

Serab

Что-то мне кажется, что если делать так, как ты рекомендуешь, то можно уже начать проверять, что присваивание переменных действительно удалось. Строки и контейнеры владеют своим буфером, в этом как бэ их смысл.

Dasar

А по делу, если в строке будет что-нить не из ASCII-набора (например, русские буквы то вывод будет неправильный
это ты про случай, когда консоль не уникодная?

Serab

А по делу, если в строке будет что-нить не из ASCII-набора (например, русские буквы то вывод будет неправильный
откуда дровишки?

Serab

А, wcout...

agent007new

Ага

Ventalf

внутри bstr-строки - могут встречать символы с кодом 0, а не только как концевой
можно подробнее?
я почти уверен, что проблема в этом
какие еще нестандартные для wstring-а cимволы могут встречаться?

agent007new

какие еще нестандартные для wstring-а cимволы могут встречаться?
Для wstring все символы стандартные, создавай строку, как я тебе показал (с указанием длины строки но на консоль все равно будет выводиться до первого нуля

Ventalf

_bstr_t tmp = this->recordsetPtr->GetFields->Item[fieldName]->Value;
return std::wstring( tmp );

или
return	std::wstring(tmp, tmp.length

или
return	std::wstring(static_cast <wchar_t *>(tmptmp.length;

работает одинаково без какой либо разницы.

Serab

Выводи куда-нибудь длину получающейся строки, а не саму строку.

Serab

И что значит работает одинаково? Судя по посту выше, у тебя еще нету теста, который гарантированно валит программу. Или я ошибаюсь? Надо тестить именно на нем, а не просто на чем-нибудь рандомном.

agent007new

Тот способ, который я указал, гарантирует то, что в создаваемую строку будет скопирована вся исходная строка. По поводу неправильного вывода я писал раньше, почему это может быть, попробуй в файл, например, выведи (но не через fstream, там такая же петрушка будет а не на консоль
Оставить комментарий
Имя или ник:
Комментарий: