Guide to BSTR and C String Conversions

Environment: VC++ 6.0, Windows

Introduction

One of the confusing aspects of Windows programming is managing the conversion of Visual Basic style strings to/from C language style strings. It isn't that it is so difficult, it is just difficult to remember the details. It is usually not done often, and the MSDN documentation is so voluminous that it is difficult to find answers to your questions. But, the worst part is that you could perform some typecast that compiles fine, but doesn't work the way you expect. This results in code that doesn't work, and the bugs are hard to track down. After some experience, you learn to make sure your string conversions are doing what you expect.

C strings are arrays of characters terminated by a NULL character. Visual Basic strings differ in that the length of the string precede the characters in the string. So, a VB string knows its own length. In addition, all VB strings are Unicode (16 bits per character).

String Types

BSTR/C String conversions are required if:

  • You are doing COM programming in C/C++
  • You are writing multiple language applications, such as C++ DLL's accessed by Visual Basic applications.

C Language String Types and Classes

This article deals with the following C/MFC/ATL string types:

String Type Description
char/wchar/TCHAR   The C strings for ANSI and Unicode
CString The C++/MFC class wrapper for C strings
BSTR The Visual Basic string type
_bstr_t A C++ class wrapper for the Visual Basic string type
CComBSTR Yet another C++ class wrapper for the Visual Basic string type used predominately in ATL code

Demo Project

The demo project is just an MFC dialog-based application with buttons for each type of conversion. It is built using VC++ 6.0. It uses a couple of support functions you may find helpful:

BSTR GetBSTR()
{
  _bstr_t bstr1(_T("This is the test string."));

  BSTR bstr;

  bstr = bstr1.copy();

  return bstr;
}




CComBSTR GetComBSTR()
{
  CComBSTR bstr("This is the test string.");

  return bstr;
}


void CVbsDlg::ShowBSTR(BSTR bstr)
{
  _bstr_t bstrStart(bstr); 

  CString s;

  s.Format(_T("%s"), (LPCTSTR)bstrStart);

  AfxMessageBox(s);

}

Conversions

So, let's get to it. Here are the conversion techniques:

  1. Converting BSTR to _bstr_t
  2.   // BSTR to _bst_t
    
      BSTR bstrStart = GetBSTR();
    
      // use the constructor
      _bstr_t bstrFinal(bstrStart);
    
      ShowBSTR(bstrFinal);
    
      // Use the = operator
      bstrFinal = bstrStart;
    
      ShowBSTR(bstrFinal);
    
  3. Converting a _bstr_t to BSTR

    You may want to get a BSTR from a _bstr_t class.

      // _bstr_t to BSTR
    
      _bstr_t bstrStart(_T("This is the test string."));
    
      BSTR bstrFinish;
    
      // use _bstr_t::copy member function
      bstrFinish = bstrStart.copy();
    
      ShowBSTR(bstrFinish);
    
      // use = operator
      bstrFinish = bstrStart;
    
      ShowBSTR(bstrFinish);
    
  4. Converting a CComBSTR to BSTR

    You may want to get a BSTR from a CComBSTR class.

      // CComBSTR to BSTR
      CComBSTR bstrStart(_T("This is the test string."));
    
      BSTR bstrFinish;
    
      // use the = operator
      bstrFinish = bstrStart;
    
      ShowBSTR(bstrFinish);
    
      // use the Copy member function
      bstrFinish = bstrStart.Copy();
    
      ShowBSTR(bstrFinish);
    
  5. Converting _bstr_t to CComBSTR

      // _bstr_t to CComBSTR
      _bstr_t bstrStart(_T("This is the test string."));
    
      CComBSTR bstrFinish;
    
      bstrFinish.AppendBSTR(bstrStart);
    
      ShowBSTR(bstrFinish);
    
  6. Converting BSTR to C String

    (Note: conversion that only works in Unicode)

      // BSTR to C String
    
      BSTR bstrStart;
    
      bstrStart = GetBSTR();
    
      TCHAR szFinal[255];
    
      // direct conversion from BSTR to LPCTSTR only works
      // in Unicode
      _stprintf(szFinal, _T("%s"), (LPCTSTR)bstrStart);
      AfxMessageBox(szFinal);
    
      _bstr_t bstrIntermediate(bstrStart);    // convert to
                                              // _bstr_t
      CString strFinal;
    
      // you have to go through _bstr_t to have it work in ANSI
      // and Unicode
      _stprintf(szFinal, _T("%s"), (LPCTSTR)bstrIntermediate);
    
      // Or, using MFC
    
      strFinal.Format(_T("%s"), (LPCTSTR)bstrIntermediate);
    
      AfxMessageBox(strFinal);
    
  7. Converting _bstr_t to C String

    (this works in both ANSI and Unicode)

      _bstr_t bstrStart(_T("This is the test string."));
      TCHAR szFinal[255];
    
      _stprintf(szFinal, _T("%s"), (LPCTSTR)bstrStart);
    
      AfxMessageBox(szFinal);
    
  8. Converting CComBSTR to LPCTSTR

    (not possible; must go through _bstr_t)

      // CComBSTR to C String
      CComBSTR bstrStart("This is the test string.");
    
      _bstr_t bstrIntermediate(bstrStart);
    
      TCHAR szFinal[255];
    
      _stprintf(szFinal, _T("%s"),
                (LPCTSTR)bstrIntermediate);
    
      AfxMessageBox(szFinal);
    
  9. Converting LPCTSTR to _bstr_t

    Use a constructor or = operator

      // LPCTSTR to _bstr_t
    
      LPCTSTR szStart = _T("This is the text string");
    
      // Use the constructor
      _bstr_t bstrFinal(szStart);
    
      ShowBSTR(bstrFinal);
    
      // or use = operator
      bstrFinal = szStart;
    
      ShowBSTR(bstrFinal);
    
  10. Converting LPCTSTR to CComBSTR

    Use a constructor or CComBSTR::Append function

      // LPCTSTR to CComBSTR
    
      // Use a constructor
    
      LPCTSTR szStart = _T("This is the text string");
    
      // Use the constructor
      CComBSTR bstrFinal(szStart);
    
      ShowBSTR(bstrFinal);
    
      // Or use the Append function
      bstrFinal.Empty();
      bstrFinal.Append(szStart);
    
      ShowBSTR(bstrFinal);
    

Well, I tested all of the conversions in the demo project. If you need to try others, download the demo for easy modification. I am sure I will hear if there are any mistakes!

Downloads

Download demo project - 28 Kb


Comments

  • Good article

    Posted by Legacy on 12/19/2003 12:00am

    Originally posted by: Abhilash

    This was one page i was looking for

    :) nice and useful .

    - Abhi

    Reply
  • Provided a lead when none was apparent.

    Posted by Legacy on 10/07/2003 12:00am

    Originally posted by: Hermione

    Provided a lead when none was apparent.
    

    Reply
  • Loved that article. Great job

    Posted by Legacy on 09/25/2003 12:00am

    Originally posted by: girish

    Loved that article. Great job

    Reply
  • cool & useful

    Posted by Legacy on 08/21/2003 12:00am

    Originally posted by: leran

    I found this article very friendly and useful.
    Keep up the good work mate.

    Reply
  • Annother conversion...

    Posted by Legacy on 08/20/2003 12:00am

    Originally posted by: MoBo

    // notional code only
    BSTR bstrStart;

    bstrStart = GetBSTR();

    TCHAR szFinal[255];

    #ifdef UNICODE
    _stprintf(szFinal, _T("%s"), (BSTR)bstrStart);
    #else
    _stprintf(szFinal, _T("%S"), (BSTR)bstrStart);
    #endif

    AfxMessageBox(szFinal);

    Reply
  • Guys, let's stop comments like Brian's and others boors.

    Posted by Legacy on 08/19/2003 12:00am

    Originally posted by: Artem

    Whats wrong?OK,even if author of some post dosn't discovered nothing new for many of us, so what? That's a reson to behave as some pithecanthrope?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • 10 Rules that Make or Break Enterprise App Development Projects In today's app-driven world, application development is a top priority. Even so, 68% of enterprise application delivery projects fail. Designing and building applications that pay for themselves and adapt to future needs is incredibly difficult. Executing one successful project is lucky, but making it a repeatable process and strategic advantage? That's where the money is. With help from our most experienced project leads and software engineers, …

  • Best-in-Class organizations execute on a strategy that supports the multi-channel nature of customer requests. These leading organizations do not just open up their service infrastructures to accommodate new channels, but also empower their teams to deliver an effective and consistent experience regardless of the channel selected by the customer. This document will highlight the key business capabilities that support a Best-in-Class customer engagement strategy.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds