私はレガシーアプリケーションで作業しており、オプションでコンパイルされたアプリケーションとオプションでコンパイルされたアプリケーションの違いを理解しようとしていMulti byte character set
ます。Not Set
Character Set
Multi byte character set
defineを使用してコンパイルする_MBCS
と、マルチバイト文字セットのコード ページを使用できるようになりますが、 Not set
defineを使用する_MBCS
と、シングル バイト文字セットのコード ページのみが使用できるようになることを理解しています。
これNot Set
を使用する場合、次のページにあるシングル バイト文字セットのコード ページしか使用できないと想定しています: http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx
したがって、Not Set
2 バイト文字セットのコード ページ (そしてもちろん Unicode) で定義されているため、アプリケーションは極東言語をエンコードしたり、読み書きしたりできません。
これに続いて、Multi byte character
set が定義されている場合、シングルバイト文字セットとマルチバイト文字セットの両方のコード ページが利用可能ですか、それともマルチバイト文字セット コード ページのみが利用可能ですか? ヨーロッパ言語をサポートするには、両方が必要だと思います。
ありがとう、
アンディ
参考文献
これらのページの回答は私の質問には答えませんでしたが、私の理解には役立ちました: Visual Studio 2010 の「文字セット」オプションについて
リサーチ
というわけで、研究のように… ロケールを日本語に設定して
ハードコードされた文字列への影響
char *foo = "Jap text: テスト";
wchar_t *bar = L"Jap text: テスト";
でコンパイルUnicode
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (コード ページ 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 または UCS-2
でコンパイルMulti byte character set
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (コード ページ 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 または UCS-2
でコンパイルNot Set
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (コード ページ 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 または UCS-2
結論: 文字エンコーディングは、ハードコードされた文字列には影響しません。上記のように文字を定義すると、ロケールで定義されたコードページが使用されているように見えますが、wchar_t は UCS-2 または UTF-16 を使用しているようです。
Win32 API の W/A バージョンでエンコードされた文字列を使用する
したがって、次のコードを使用します。
char *foo = "C:\\Temp\\テスト\\テa.txt";
wchar_t *bar = L"C:\\Temp\\テスト\\テw.txt";
CreateFileA(bar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CreateFileW(foo, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
でコンパイルUnicode
結果: 両方のファイルが作成されます
でコンパイルMulti byte character set
結果: 両方のファイルが作成されます
でコンパイルNot set
結果: 両方のファイルが作成されます
結論:A
選択した文字セットに関係なく、API のとバージョンの
両方がW
同じエンコーディングを想定しています。Character Set
このことから、おそらく、すべてのオプションは API のバージョンを切り替えるだけであると推測できます。そのため、A
バージョンは常に現在のコード ページのエンコーディングの文字列を想定し、W
バージョンは常に UTF-16 または UCS-2 を想定しています。
W および A Win32 API を使用してファイルを開く
したがって、次のコードを使用します。
char filea[MAX_PATH] = {0};
OPENFILENAMEA ofna = {0};
ofna.lStructSize = sizeof ( ofna );
ofna.hwndOwner = NULL ;
ofna.lpstrFile = filea ;
ofna.nMaxFile = MAX_PATH;
ofna.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofna.nFilterIndex =1;
ofna.lpstrFileTitle = NULL ;
ofna.nMaxFileTitle = 0 ;
ofna.lpstrInitialDir=NULL ;
ofna.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
wchar_t filew[MAX_PATH] = {0};
OPENFILENAMEW ofnw = {0};
ofnw.lStructSize = sizeof ( ofnw );
ofnw.hwndOwner = NULL ;
ofnw.lpstrFile = filew ;
ofnw.nMaxFile = MAX_PATH;
ofnw.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
ofnw.nFilterIndex =1;
ofnw.lpstrFileTitle = NULL;
ofnw.nMaxFileTitle = 0 ;
ofnw.lpstrInitialDir=NULL ;
ofnw.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
GetOpenFileNameA(&ofna);
GetOpenFileNameW(&ofnw);
次のいずれかを選択します。
- C:\Temp\テスト\テopenw.txt
- C:\Temp\テスト\テopenw.txt
収量:
でコンパイルするとUnicode
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (コードページ 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 または UCS-2
でコンパイルするとMulti byte character set
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (コードページ 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 または UCS-2
でコンパイルするとNot Set
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (コードページ 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 または UCS-2
結論:
繰り返しますが、Character Set
設定は Win32 API の動作には影響しません。バージョンはA
常にアクティブなコード ページのエンコーディングを含む文字列を返すようで、W
常に UTF-16 または UCS-2 を返します。私は実際にこれがこの素晴らしい答えで少し説明されているのを見ることができます: https://stackoverflow.com/a/3299860/187100。
究極の脳震盪
W
Win32 API を または のいずれかを使用するように変更する以外に、define には実際には何の魔法もないという Hans の言葉は正しいようA
です。Not Set
したがって、との違いはほとんどわかりませんMulti byte character set
。