SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

BSTRおよびC文字列の変換

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

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

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

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

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

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Robert Pittenger(Robert Pittenger)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/25 2008/08/19 20:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング