12

私はレガシーアプリケーションで作業しており、オプションでコンパイルされたアプリケーションとオプションでコンパイルされたアプリケーションの違いを理解しようとしていMulti byte character setます。Not SetCharacter Set

Multi byte character setdefineを使用してコンパイルする_MBCSと、マルチバイト文字セットのコード ページを使用できるようになりますが、 Not setdefineを使用する_MBCSと、シングル バイト文字セットのコード ページのみが使用できるようになることを理解しています。

これNot Setを使用する場合、次のページにあるシングル バイト文字セットのコード ページしか使用できないと想定しています: http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx

したがって、Not Set2 バイト文字セットのコード ページ (そしてもちろん Unicode) で定義されているため、アプリケーションは極東言語をエンコードしたり、読み書きしたりできません。

これに続いて、Multi byte characterset が定義されている場合、シングルバイト文字セットとマルチバイト文字セットの両方のコード ページが利用可能ですか、それともマルチバイト文字セット コード ページのみが利用可能ですか? ヨーロッパ言語をサポートするには、両方が必要だと思います。

ありがとう、

アンディ

参考文献

これらのページの回答は私の質問には答えませんでしたが、私の理解には役立ちました: 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

究極の脳震盪

WWin32 API を または のいずれかを使用するように変更する以外に、define には実際には何の魔法もないという Hans の言葉は正しいようAです。Not Setしたがって、との違いはほとんどわかりませんMulti byte character set

4

2 に答える 2

8

いいえ、実際にはそうではありません。発生する唯一のことは、マクロが定義されることです。それ以外の場合、コンパイラに魔法のような効果はありません。このマクロをテストするために使用するコードを実際に書くことは非常にまれです。#ifdef _MBCS

ほとんどの場合、変換はヘルパー関数に任せます。WideCharToMultiByte()、OLE2A()、または wctombs() と同様です。コードページに従って、常にマルチバイトエンコーディングを考慮する変換関数です。_MBCS は歴史的な事故であり、マルチバイト エンコーディングがまだ一般的ではなかった 25 年以上前に関連しています。非 Unicode エンコーディングを使用するのと同じように、最近では歴史的なアーティファクトでもあります。

于 2013-07-19T11:33:51.767 に答える