2015-07-09 1 views
3

Как бы вы конвертировали std::string в BSTR*?Как бы вы преобразовали std :: string в BSTR *?

STDMETHODIMP CMyRESTApp::rest(BSTR data, BSTR* restr) 
{ 
    RESTClient restclient; 
    RESTClient::response resp = restclient.get(data); 

    Log("Response Status code: %s", resp.code); 
    Log("Response Body: %s", resp.body); 

    *restr = // here 
    return S_OK; 
} 

мне нужно преобразовать resp.body и это затем возвращается к *restr здесь.

+0

Зависит. Что такое 'BSTR *'? Пометьте библиотеку, которую вы используете. –

ответ

7

АТЛ подход, основанный на использовании ATL::CComBSTR, а затем Detach() (или CopyTo(...)) в результате CComBSTR к BSTR*

Что-то вроде:

CComBSTR temp(stlstr.c_str()); 
*restr = temp.Detach(); 

Else в целом для std::basic_string вы можете использовать Win32 API Sys* семейство функций, таких как SysAllocStringByteLen и SysAllocString;

// For the `const char*` data type (`LPCSTR`); 
*restr = SysAllocStringByteLen(stlstr.c_str(), stlstr.size()); 

// More suitable for OLECHAR 
*restr = SysAllocString(stlwstr.c_str()); 

OLECHAR зависит от целевой платформы, но в целом это wchar_t.

С учетом вашего кода самым коротким фрагментом может быть;

*restr = SysAllocStringByteLen(resp.body.c_str(), resp.body.size()); 

Примечание эти функции Windows API, использует преобразование страниц «обычное» окно кода, смотрите дополнительную документацию MSDN о том, как управлять этим, если это необходимо.

+0

В отношении комментария «зависит от основного символа»: вопрос задает вопрос о преобразовании из 'std :: string', а не из' std :: wstring' или из произвольного 'std :: basic_string '. – jamesdlin

+0

@jamesdlin. Правильно, это был общий комментарий. Я проясню это в ответе. – Niall

+0

У меня есть некоторое беспокойство по поводу этого кода: 'CComBSTR temp (stlstr.c_str());'. Хотя я знаю, что есть конструктор 'CComBSTR', который принимает' const char * ', поэтому этот код, безусловно, будет компилироваться, я не уверен, что такое преобразование« кодовой страницы », которое реализует этот конструктор. Например, я не верю, что он конвертирует из UTF-8 (возможный контент из 'std :: string') в UTF-16 (для' BSTR'). Такие неясные двусмысленные преобразования могут вызывать тонкие ошибки с международным текстом. Я бы предложил использовать код, который делает * явные преобразования * из любого формата, который 'std :: string' использует для UTF-16 для' BSTR'. –

0
size_t sztBuffer = (resp.body.length() + 1) * sizeof(wchar_t); 
wchar_t* pBuffer = new wchar_t[resp.body.length() + 1]; 
ZeroMemory(&pBuffer[0], sztBuffer); 
MultiByteToWideChar(CP_ACP, 0, resp.body.c_str(), resp.body.length(), pBuffer, sString.length());  
SysAllocString((OLECHAR*)pBuffer); 
delete[] pBuffer; 

Не забудьте освободить его после этого.

+3

Этот последний абзац очень бесполезен, это не контракт. –

+1

Я не вижу, как это может работать, если 'resp.body' является' std :: string' (а не 'std :: wstring'), о чем и спрашивается. – jamesdlin

+0

Вы, конечно, правы. Чтобы использовать этот подход с std :: string, он должен быть сначала преобразован в Unicode. – Ari0nhh

2

std::string сделан char s; BSTR обычно является строкой Unicode UTF-16 wchar_t с префиксом длины.

Даже если можно было бы использовать BSTR как простой способ маршала массив байтов (так как это BSTR длина префикса, поэтому она может хранить встроенные NULs), и так потенциально BSTR может быть использовано также для хранения не- UTF-16, обычный «естественный» режим для BSTR должен содержать Unicode UTF-16 wchar_t -строка.

Итак, первая проблема заключается в уточнении какого рода кодирующая std::string использует (например: Unicode UTF-8 или какой-либо другой код страницы?). Затем вам нужно преобразовать эту строку в Unicode UTF-16 и создать BSTR, содержащий эту строку UTF-16.

Для преобразования из UTF-8 (или другой кодовой страницы) в UTF-16 вы можете использовать MultiByteToWideChar() function. Если источник std::string содержит строку UTF-8, вы можете использовать значение кодовой страницы CP_UTF8 с вышеупомянутым API.

После того, как вы создали преобразованную строку UTF-16, вы можете создать ее с помощью BSTR и передать это как параметр вывода BSTR*.

Основной Win32 API для создания BSTR - SysAllocString(). Существуют также некоторые варианты, в которых вы можете указать длину строки.

Или, как более удобную альтернативу, вы можете использовать CComBSTR класс в ATL, чтобы обернуть в пределах безопасных RAII в BSTR, и использовать его Detach() method передать BSTR в качестве выходного параметра BSTR*. чтение

CComBSTR bstrResult(/* UTF-16 string from std::string */); 
*restr = bstrResult.Detach(); 

Бонус:

Eric's Complete Guide To BSTR Semantics

+0

Другим вариантом является [_bstr_t Class] (https://msdn.microsoft.com/en-us/library/zthfhkd6.aspx), доступный как [класс поддержки компилятора COM] (https://msdn.microsoft.com). /en-us/library/5yb2sfxk.aspx) в Visual Studio, если вам не нужна зависимость от ATL. – IInspectable

0

Это очень возможно:

std::string singer("happy new year 2016"); 
_bstr_t sa_1(singer.c_str()); //std::string to _bstr_t 
_bstr_t sa_2("Goodbye 2015"); 
std::string kapa(sa_2); //_bstr_t to std::string 
+0

И как вы конвертируете _bstr_t в BSTR? вопрос задает std :: string для BSTR – AaA

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