How would you convert a std::string to BSTR*?
Solution 1
An ATL based approach is to use ATL::CComBSTR
and then a Detach()
(or CopyTo(...)
) the resultant CComBSTR
to the BSTR*
Something like:
CComBSTR temp(stlstr.c_str());
*restr = temp.Detach();
Else in general for std::basic_string
you can use the Win32 API Sys*
family of functions, such as SysAllocStringByteLen
and 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
depends on the target platform, but generally it is wchar_t
.
Given your code, the shortest snippet could just be;
*restr = SysAllocStringByteLen(resp.body.c_str(), resp.body.size());
Note these Windows API functions use the "usual" windows code page conversions, please see further MSDN documentation on how to control this if required.
Solution 2
std::string
is made by char
s; BSTR
is usually a Unicode UTF-16 wchar_t
-based string, with a length prefix.
Even if one could use a BSTR
as a simple way to marshal a byte array (since the BSTR
is length-prefixed, so it can store embedded NULs), and so potentially a BSTR
could be used also to store non-UTF-16 text, the usual "natural" behavior for a BSTR
is to contain a Unicode UTF-16 wchar_t
-string.
So, the first problem is to clarify what kind of encoding the std::string
uses (for example: Unicode UTF-8? Or some other code page?). Then you have to convert that string to Unicode UTF-16, and create a BSTR
containing that UTF-16 string.
To convert from UTF-8 (or some other code page) to UTF-16, you can use the MultiByteToWideChar()
function. If the source std::string
contains a UTF-8 string, you can use the CP_UTF8
code page value with the aforementioned API.
Once you have the UTF-16 converted string, you can create a BSTR
using it, and pass that as the output BSTR*
parameter.
The main Win32 API to create a BSTR
is SysAllocString()
. There are also some variants in which you can specify the string length.
Or, as a more convenient alternative, you can use the ATL's CComBSTR
class to wrap a BSTR
in safe RAII boundaries, and use its Detach()
method to pass the BSTR
as an output BSTR*
parameter.
CComBSTR bstrResult( /* UTF-16 string from std::string */ );
*restr = bstrResult.Detach();
Bonus reading:
Solution 3
This is very much possible :
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
Related videos on Youtube
xkm
Updated on September 14, 2022Comments
-
xkm over 1 year
How would you convert a
std::string
toBSTR*
?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; }
I need convert the
resp.body
and this then to be returned for the*restr
here. -
user1703401 almost 9 yearsThat last paragraph is very unhelpful, it is not the contract.
-
jamesdlin almost 9 yearsI do not see how this can work if
resp.body
is astd::string
(rather than astd::wstring
), which is what the question is asking about. -
jamesdlin almost 9 yearsRegarding the "depends on underlying char type" comment: the question specifically asks about converting from a
std::string
, not from astd::wstring
or from an arbitrarystd::basic_string<T>
. -
Niall almost 9 years@jamesdlin. Correct, this was a general comment. I'll clear that up in the answer.
-
Ari0nhh almost 9 yearsYou are right of course. To use this approach with std::string it must be converted to Unicode first.
-
IInspectable almost 9 yearsAnother alternative is the _bstr_t Class, available as a Compiler COM Support Class in Visual Studio, if you do not want a dependency on ATL.
-
IInspectable almost 9 yearsThe code is using a
std::string
. No need to not use astd::vector<wchar_t>
, instead of the clunky array. Plus, your math for calculating the required buffer size is wrong. LetMultiByteToWideChar
do the math for you. -
Mr.C64 almost 9 yearsI have some concern about this code:
CComBSTR temp(stlstr.c_str());
. While I know there is aCComBSTR
constructor taking aconst char*
, so this code would certainly compile, I'm not sure what kind of "code page" conversion this constructor implements. For example, I don't believe it converts from UTF-8 (possible content of thestd::string
) to UTF-16 (for theBSTR
). Those kind of unclear ambiguous conversions can cause subtle bugs with international text. I'd suggest using code that does explicit conversions from whatever format thestd::string
uses to UTF-16 for theBSTR
. -
AaA almost 8 yearsAnd how you convert _bstr_t to BSTR? question is asking std::string to BSTR