티스토리 뷰

프로그래밍Tip

BSTR vs. C String

이성권 2013. 7. 3. 12:29

윈도우 프로그래밍을 하다 보면, 가끔 혼동이 오는 부분이 있는데, Visual Basic 스타일의 string과 C 언어 스타일 string의 변환이 바로 그것이다. 

사실 이것은 어렵다기 보다는 상세히 기억하기가 어려운 경우라고 할 수 있다.  


C string은 NULL문자로 끝나는 문자열이다. Visual Basic string은 문자열의 시작부에 문자열의 길이 값을 가지고 있다. 그래서, VB sting은 그 문자열의 길이를 알고 있다. 게다가, 모든 VB string은 Unicode(16bits)이다. 


String Types

BSTR/C 스트링 변환은 다음과 같은 경우에 필요하다.

  • C/C++로 COM 프로그래밍을 하는 경우
  • 다중 언어 프로그래밍을 하는 경우, C++ DLL을 Visual Basic응용에서 액세스하는 경우

C언어 string 타임과 클래스

이 글은 다음 C/MFC/ATL 스트링 형에 대해 다룬다.


  • char/wchar/TCHAR -- ANSI와 Unicode를 위한 C string 
  • CString -- C string에 대한 C++/MFC 클래스 래퍼 
  • BSTR -- Visual Basic string type
  • _bstr_t -- Visual Basic string type에 대한  C++ 클래스 래퍼
  • CComBSTR -- Visual Basic string에 대한 또 다른 C++ 클래스 래퍼


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);

}



변환

1) BSTR -> _bstr_t

    // BSTR to _bst_t

    BSTR bstrStart = GetBSTR();


    // use the constructor

    _bstr_t bstrFinal(bstrStart);


    ShowBSTR(bstrFinal);


    // Use the = operator

    bstrFinal = bstrStart;


    ShowBSTR(bstrFinal);


2) _bstr_t -> BSTR

 // _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);



3) CComBSTR -> BSTR

 // 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);

4) _bstr_t to CComBSTR

    // _bstr_t to CComBSTR

    _bstr_t bstrStart(_T("This is the test string."));


    CComBSTR bstrFinish;  


    bstrFinish.AppendBSTR(bstrStart);


    ShowBSTR(bstrFinish);


5) BSTR -> C String

** 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);


6) _bstr_t -> C string

** 이 코드는 ANSI 및 Unicode에서 동작한다.

    _bstr_t bstrStart(_T("This is the test string.")); 

    TCHAR szFinal[255];


    _stprintf(szFinal, _T("%s"), (LPCTSTR)bstrStart);


    AfxMessageBox(szFinal);


7) CComBSTR -> LPCTSTR

** 불가능하며, _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);


8) LPCTSTR -> _bstr_t

** 생성자 또는 = 연산자 사용

    // 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);


9) LPCTSTR -> CComBSTR

** 생성자 또는  CComBSTR::Append 함수 사용

    // 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);