4

I am simply trying to convert _bstr_t into std::string..

I found a post on this issue (LINK), and did exactly as described, but it is raising exception..

This is what I did:

_bstr_t BString;
std::string STDString((char *) BString);

And I get this error:

0CxC00000005: Access violation reading location 0x00000000

Specifically, after looking at the call stack, error in iosfwd.h:

static size_t __CLRCALL_OR_CDECL length(const _Elem *_First)
    {   // find length of null-terminated string
    return (*_First == 0 ? 0
        : _CSTD strlen(_First));
    }


What is the right way to convert _bstr_t to std::string..?

Thanks

user2436815
  • 3,455
  • 5
  • 27
  • 40
  • @MooingDuck Just edited the code.. yes it is _bstr_t – user2436815 Jul 02 '14 at 20:27
  • Note that `BString` probably uses UTF16 internally, and so the `char*` overload will use the current locale to choose a byte encoding, probably CP-1252, resulting in some characters being unable to be converted properly. – Mooing Duck Jul 02 '14 at 20:27
  • 1
    Either the post you linked to is full of crap, or compiling with `/clr` somehow makes the code in there work. A `_bstr_t` is a wrapper around a COM `BSTR`, which stores the length of the string in the first 4 bytes. So a cast is not going to do the job. Edit: Ah, I see how it works ... `_bstr_t` defines [implicit conversion operators](http://msdn.microsoft.com/en-us/library/btdzb8eb.aspx) to `char *` and `whcar_t *`. – Praetorian Jul 02 '14 at 20:29
  • @Praetorian Oops, I misread and retracted the close vote. Again: Possible duplicate of [BSTR to std::string (std::wstring) and vice versa](http://stackoverflow.com/questions/6284524/bstr-to-stdstring-stdwstring-and-vice-versa?lq=1) – πάντα ῥεῖ Jul 02 '14 at 20:34
  • @πάνταῥεῖ: Every answer on that page has the same bug as this question is encountering. Since no answer on that page answers this question, I hesitate to close this as a dupe of that. Maybe once that page has a better answer. – Mooing Duck Jul 02 '14 at 20:38
  • @MooingDuck Yup, you're right. None of the answers handles NULL or empty `bstr_t` values correctly. – πάντα ῥεῖ Jul 02 '14 at 20:43

1 Answers1

4

BString can hold a null value, wheras std::string cannot, so you'll have to account for this.

const char* buf = BString;
int bstrlen = BString.length();
std::string STDString( buf?buf:"", bstrlen);

Note that BString probably uses UTF16 internally, and so the char* overload will use the current locale to choose a byte encoding, probably CP-1252, resulting in some characters being unable to be converted properly.

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • No need for the initial cast in the conditional. – Konrad Rudolph Jul 02 '14 at 20:36
  • @KonradRudolph: I hadn't tested, but since it has four implicit conversions that are valid in a boolean context, I figured not having the cast would result in a "ambiguity" compiler error. – Mooing Duck Jul 02 '14 at 20:40
  • @KonradRudolph "`error C2440: '?' : cannot convert from '_bstr_t' to 'bool' Ambiguous user-defined-conversion`" http://rextester.com/HPES3175 – Mooing Duck Jul 02 '14 at 20:42