В этом посту мы разберем как работать со строками BSTR, эти строки применяются в COM, потому что строки COM должны быть универсальными для всех языков. Например в С++ строка это массив символов заканчивающийся нулем, а в других языках это может быть по другом. От поэтому используется в COM свой тип строк который называется базовым BSTR.
Определение BSTR
Посмотрим определение BSTR
1 |
typedef /* [wire_marshal] */ OLECHAR *BSTR; |
как видно BSTR это указатель на OLECHAR, посмотрим определение OLECHAR
1 |
typedef WCHAR OLECHAR; |
и определение WCHAR
1 |
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character |
это указатель на широкие строки как видно из кода. Можно просто сказать что BSTR это wchar_t* .
Выделение памяти для BSTR (SysAllocString и SysFreeString)
Для BSTR строк вроде нужно выделять память, а затем удалять память, для этого существуют функции SysAllocString и SysFreeString, вот пример их использования
1 2 3 |
BSTR s1=SysAllocString(L"Hellow world");//выделяем память TRACE("s1 = %S\n",s1); SysFreeString(s1);//освобождаем память |
Класс для работы с BSTR (_bstr_t)
[warning]Для того чтобы этот класс стал доступен нужно подкючить файл comutil.h
1 |
#include "comutil.h" |
[/warning]
Для удобной работы с BSTR строками существует специальный класс _bstr_t, за него можно почитать тут. Очень удобный класс, просто оборачиваем строку в него и можно со строкой делать все что угодно, конкатенация доступна и сравнения. Вот небольшой примерчик использования _bstr_t
1 2 3 4 5 6 7 8 9 10 11 12 13 |
BSTR temp; html->get_innerHTML(&temp); _bstr_t text2(L"<script type=\"text/javascript\">\n"); text2+=_bstr_t(L"alert('hellow world!');\n"); text2+=L"document.getElementById('ps_text').innerHTML=\"hellow soski\";\n"; text2+=L"$(\"#ps_text\").html(\"+7 (923) 775-38-68, 8-383-375-38-68<br>\");\n"; text2+=L"</script>\n"; _bstr_t b(temp); b+=text2.copy(); std::string temp1=_com_util::ConvertBSTRToString(b.Detach()); std::ofstream ofss1("data2.html",std::ofstream::out); ofss1 <<temp1<<"\n"; |
Перевод из BSTR в String и обратно
для того чтобы перевести из BSTR в string существуют специальные функции, они находятся в заголовочном файле comutil.h, чтобы их использовать вы его должны подключить. Там есть две функции вот их прототипы
1 2 |
BSTR __stdcall ConvertStringToBSTR(const char* pSrc); char* __stdcall ConvertBSTRToString(BSTR pSrc) ; |
находятся они в пространстве имен _com_util. Вот пример их использования
1 2 3 4 5 6 7 8 9 10 11 |
//запись в файл std::stringstream ss; ss <<"i= "<<i<<"-----------------------\n"; s2+=_com_util::ConvertStringToBSTR(ss.str().c_str()); s2+=s1; s2+="--------------------------------\n"; std::string temp1=_com_util::ConvertBSTRToString(s2.Detach()); std::ofstream ofss1("text.html",std::ofstream::app); ofss1 <<temp1<<"\n"; //// |
Как из VARIANT получить BSTR
Бывает часто нужно из VARIANT получить BSTR, это легко делается, нужно просто вызвать вот например так _bstr_t(v), где v — переменная типа VARIANT и примерчик кода
1 2 3 4 5 6 7 8 9 10 |
VARIANT atrVal; if(pElem->getAttribute(L"href",0,&atrVal)==S_OK) { if(_bstr_t(atrVal)==_bstr_t(L"https://www.fl.ru/projects/")) { TRACE("atr=%S\n",_bstr_t(atrVal).Detach()); pElem->click(); return; } } |