VCでプログラミングをしています。基本的なことなのですが質問があります。教えてください。


1._T()を使ったコードでマルチバイドでコンパイルしてもエラーになりません。これは無視されるのでしょか?また、出来たコードは_T()で囲っていてもマルチバイトでしょうか(Unicodeではない)?

2.例えばMessageBox関数を利用するとWindows APIのMessageBoxAあるいはMessageBoxWが最終的に呼ばれると思います。どちらを呼ぶかはコンパイルあるいはリンクした際に決まるのでしょうか?

3.PCWSTRとLPCWSTRは同じWCHRで16BIT UNICODEなのでしょうか?

4.仮にプログラムから直接MessageBoxWを呼ぶとき、マルチバイトでコンパイルして引数がUNICODEでないマルチバイトを渡したとき、どうやってMessageBoxWはUNICODEとして扱うのでしょうか?コンパイルエラーならずに正しく実行できるようです。

以上、よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/03/23 20:53:35
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:JULY No.1

回答回数966ベストアンサー獲得回数247

ポイント34pt

1._T()を使ったコードでマルチバイドでコンパイルしてもエラーになりません。これは無視されるのでしょか?また、出来たコードは_T()で囲っていてもマルチバイトでしょうか(Unicodeではない)?

tchar.h を見れば分かると思います。

_T() マクロは、__T()

#define _T(x)       __T(x)

と定義されていて、__T() マクロが、_UNICODE が定義されているかどうかで違っていて、

#ifdef  _UNICODE
 ~
#define __T(x)      L ## x
 ~
#else   /* ndef _UNICODE */
 ~
#define __T(x)      x
 ~
#endif  /* _UNICODE */

となっています。なので、_T("abc") は、UNICODE 時は「L"abc"」、マルチバイト時は「"abc"」に展開されます。

2.例えばMessageBox関数を利用するとWindows APIのMessageBoxAあるいはMessageBoxWが最終的に呼ばれると思います。どちらを呼ぶかはコンパイルあるいはリンクした際に決まるのでしょうか?

コンパイル時です。WinUser.h に、このように書かれています。

#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

3.PCWSTRとLPCWSTRは同じWCHRで16BIT UNICODEなのでしょうか?

同じと考えて良いです。WinNT.h で、このようになっています。

typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;

PCWSTR も LPCWSTR も同じ定義になっています。

4.仮にプログラムから直接MessageBoxWを呼ぶとき、マルチバイトでコンパイルして引数がUNICODEでないマルチバイトを渡したとき、どうやってMessageBoxWはUNICODEとして扱うのでしょうか?コンパイルエラーならずに正しく実行できるようです。

ごめんなさい。これは実際に試したことが無いので、今、「へぇ~」って思っています(^^;。

id:SweetSmile1978 No.2

回答回数199ベストアンサー獲得回数31

ポイント33pt

1:
_T() は、UNICODE が define されているかどうか
(プロジェクトの設定がユニコードになっているかどうか)によって、
ユニコードかマルチバイトかが決まります。
ですので、_T() 自体はプロジェクトの設定がマルチバイトの時でも問題ありません。
ただ、wchar_t 型やそのポインタを受け取る関数の引数としていると
コンパイルエラーが出るはずです。

2:
UNICODE がdefineされているかどうか
(プロジェクト設定でUNICODEになっているかどうか)によって
コンパイル時に決定されます。

3:
LP~系とP~系はその後が同じ名前なら同じです。
LP は Long Pointer を表し、16bit Windows 時代の遺物です。
未だに LP~系が圧倒的に多く使われるのでややこしいですね。

4:
そのコードを見てみないとなんとも言えませんね。
MessageBoxW(NULL, L"テストメッセージ", L"テスト", MB_OK);
なんてコードだとプロジェクトの設定がマルチバイトでも
コンパイルは通りますね。

id:SweetSmile1978 No.3

回答回数199ベストアンサー獲得回数31

ポイント33pt

DLL内のUNICODEを引数に必要とする関数を
通常マルチバイトを扱う実行ファイルから呼び出す場合、
Windows APIである MultiByteToWideChar関数を使用して
自分でそのマルチバイト文字列をUNICODE文字列に変換する必要があります。

  • id:mai_mai_mail
    4番目の質問について追加で質問させてください。
    仮にDLLとEXEを作ります。DLLはUNICODE、EXEはマルチバイト、この状態でDLLの関数の引数は渡す際、適切にコード変換するのは誰の役目でしょうか?

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません