CodeZine(コードジン)

特集ページ一覧

BSTRおよびC文字列の変換

Windowsプログラミングにおける文字列の扱い

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2005/04/01 00:00

Windowsプログラミングで混乱しがちな、Visual BasicスタイルとC言語スタイルの文字列の変換について解説。

はじめに

 Windowsプログラミングでは、Visual BasicスタイルとC言語スタイルの文字列の変換に混乱してしまうことがある。この変換自体はそれほど難しくはない。難しいのは、変換の細かい決まりを覚えておくことだ。一般的によく行われる処理ではない上に、MSDNには膨大な量のドキュメントがあるので、わからないことがあっても簡単には答えを見つけられない。しかし最も困るのは、型キャストを実行してコンパイルも正常にできたのに、プログラムが思いどおりに動作しないときだ。この場合コードはきちんと動作しないし、バグの原因を見つけ出すのも困難である。

 この問題を何度か経験してみると、まず文字列変換が正しくできているかどうかを確認することが重要だとわかるはずだ。C文字列は、NULL文字で終了する文字配列で、一方のVisual Basic文字列は、先頭にその文字列の長さの情報を含んでいる(VB文字列は自身の長さを認識している)。さらに、すべてのVB文字列はUnicodeである(1文字につき16ビット)。

文字列の型

 次の場合は、BSTR/C文字列の変換が必要である。

  • C/C++でCOMプログラミングを行っている場合
  • 複数言語のアプリケーション(Visual BasicアプリケーションからアクセスされるC++ DLLなど)を書いている場合

C言語の文字列の型とクラス

 ここでは、次のC/MFC/ATL文字列型を取り上げる。

文字列の型 説明
char/wchar/TCHAR ANSIおよびUnicode用のC文字列
CString C文字列用のC++/MFCクラスラッパー
BSTR Visual Basic文字列型
_bstr_t Visual Basic文字列型用のC++クラスラッパー
CComBSTR Visual Basic文字列型用のもう1つのC++クラスラッパー(主にATLコードで使用)

デモプロジェクト

 このデモプロジェクトは、MFCダイアログベースのアプリケーションに各種の変換を実行するボタンを追加しただけのものだ。これはVC++ 6.0で作成した。参考までに、このプロジェクトで使用したサポート関数を紹介しておく。

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クラスから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クラスから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からCComBSTRへの変換

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

  CComBSTR bstrFinish;

  bstrFinish.AppendBSTR(bstrStart);

  ShowBSTR(bstrFinish);

5. BSTRからC文字列への変換

 (注: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文字列への変換

 (この方法は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);

 ここで紹介した変換テクニックは、全てデモプロジェクトで動作確認済みである。他のテクニックを試したい人は、デモプロジェクトをダウンロードして修正するとよい。

 間違いがあったらぜひご報告いただきたい。



  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

バックナンバー

連載:japan.internet.com翻訳記事

もっと読む

All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5