Microsoft Game Development Kit での UTF-8 のサポート
このトピックでは、Microsoft Game Development Kit (GDK) での UTF-8 サポートの概要について説明します。
- 概要
- -A と -W API の比較
- コンソール本体のコード ページ
- Windows PC コード ページ
- MultiByteToWideChar/WideCharToMultiByte
- UTF-8 とグローバリゼーションの高度なサポートのための ICU
- 以前のバージョンの Windows のサポート
概要
UTF-8 は国際化のためのユニバーサル コード ページであり、1–4 バイトの可変幅エンコードを使用するすべての Unicode コード ポイントをサポートします。 これは Web で広く使用されており、UNIX ベースのシステムなどの競合プラットフォームは既定で UTF-8 で動作します。 UTF-8 での動作により、国際化対応のシナリオにおいて互換性を最大限に確保し、最小限の労力とテストの負担でデータ交換を行うことができます。
Windows はネイティブで UTF-16 (または WCHAR
) で動作します。そのためには、MultiByteToWideChar
と WideCharToMultiByte
を使用してコード ページを変換する必要があります。 コードが複数のプラットフォームを対象とする場合、Windows ではこの作業が発生します。 さらなる課題となるのは、Windows の ANSI コード ページの概念です。これは、地域およびユーザー構成ごとに異なる場合があります。結果として、依存関係が正しくない場合に動作の一貫性が大きく損なわれる可能性があります。
Microsoft Game Development Kit (GDK) と Windows では全般的に UTF-8 のサポートへ移行します。そして、複数のプラットフォームおよび Web に対して、対象のコードを決定したり、交換するなどの Windows で発生する作業を排除していきます。 これにより、アプリとゲームの国際化に関する問題が減少し、国際化を適切に行うために必要なテスト マトリックスが削減されます。
-A と -W API の比較
多くの場合、Win32 API は -A および -W のバリアントを提供します。
-A バリアント は、システムで設定されている ANSI コードページを尊重し、char* を扱えるようにします。
-W バリアントは、UTF-16 で動作し、WCHAR
を処理します。
最近までは、-A API がレガシと見なされていました。これは、何十年もの間、Windows が "Unicode" -W バリアントを推進していたためです。 しかし、最近のリリースの Windows では、ANSI コード ページと -A API を活用し、新しい SKU で UTF-8 サポートを導入しています。 ANSI コード ページが UTF-8 に対して構成されている場合、-A API は UTF-8 で動作します。 このモデルには、コードの変更を必要とせずに -A API を使用して作成された既存のコードをサポートするという利点があります。
Microsoft Game Development Kit (GDK) では、UTF-8 が既定であり、本体の ANSI コード ページのみです。 コンソール本体上で -A API は常に UTF-8 で稼働し、移植性を最大化するには呼び出すことをお勧めします。 既存の Windows コードとのソースの互換性を確保するために、-W API も (おそらく引き継がれる既存の PC バージョンのゲームから) 提供されます。
コンソール本体のコード ページ
UTF-8 はコンソール本体における既定および唯一のコード ページであるため、UTF-8 を十分に活用するためには -A API が推奨されます。
Windows PC コード ページ
互換性の理由から、Windows PC における既定の ANSI コード ページはレガシのままになります (地域およびユーザー構成によって異なります)。 そのため、Windows PC とコンソール本体を対象とする場合は、必然的にコード ページの変換と適切なテスト マトリックスを検討する作業が必要となります。
この問題を軽減するために、Windows では、システムのコード ページに関係なく、プロセスのコード ページとして UTF-8 を強制的にオプトインする処理を行う手段を導入しました。 これは、パッケージ アプリの appxmanifest
または ActiveCodePage
プロパティを使用するパッケージ化されていないアプリのフュージョン マニフェストを通じて実現できます。 詳細については、次のコード例を参照してください。
注意
この機能は、 Windows 19H1 以降の Windows ビルドでのみ使用できます。 このプロパティを宣言し、以前の Windows ビルドをターゲットとする、または実行することができます。 ただし、これまでのようにレガシ コード ページの検出と変換を処理する必要があります。 最小のターゲット バージョンである 19H1 では、プロセスのコード ページは常に UTF-8 になります。
appxmanifest (パッケージ化あり):
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="https://schemas.microsoft.com/appx/manifest/foundation/windows10"
...
xmlns:uap7="https://schemas.microsoft.com/appx/manifest/uap/windows10/7"
xmlns:uap8="https://schemas.microsoft.com/appx/manifest/uap/windows10/8"
...
IgnorableNamespaces="... uap7 uap8 ...">
<Applications>
<Application ...>
<uap7:Properties>
<uap8:ActiveCodePage>UTF-8</uap8:ActiveCodePage>
</uap7:Properties>
</Application>
</Applications>
</Package>
Win32 マニフェスト (パッケージ化なし):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity type="win32" name="..." version="6.0.0.0"/>
<application>
<windowsSettings>
<activeCodePage xmlns="https://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>
Note: You can add a manifest to an existing executable via the command line with mt.exe -manifest <MANIFEST> -outputresource:<EXE>;#1
MultiByteToWideChar/WideCharToMultiByte
MultiByteToWideChar と WideCharToMultiByte を使用すると、UTF-8 と UTF-16 (WCHAR
) (およびその他のコード ページ) 間で変換を行うことができます。 これは、レガシ Win32 API が WCHAR
しか理解しない場合に特に便利です。 これらの関数を使用すると、UTF-8 の入力を WCHAR
に変換して -W API に渡し、必要に応じて結果を再び変換することができます。
Microsoft Game Development Kit (GDK) でこれらの関数を使用する場合は、ドキュメントの記載どおり dwFlags
に 0 または MB_ERR_INVALID_CHARS
を指定して CodePage CP_UTF8
を使用します。 そうしないと、 ERROR_INVALID_FLAGS
のエラーが表示されます。
注意
コンソール本体では、CP_ACP
は常に CP_UTF8
と同じです。 明示的に CP_UTF8
に切り替える必要がある場合でも、既存のコードを引き続き使用できます。 Windows PC では、19H1 以降で実行されていて、前述の ActiveCodePage
プロパティが UTF-8 に設定されている場合にのみ、CP_ACP
は CP_UTF8
と等価です。 それ以外の場合は、レガシ システムのコード ページが使用されます。 今後は、CP_UTF8
を明示的に使用することがベスト プラクティスになります。
UTF-8 とグローバリゼーションの高度なサポートのための ICU
ICU は、International Components for Unicode library の略です。 C/C++ インターフェイスを使用した高度な UTF-8 の処理 (たとえば、照合、正規化、トークン化など) をサポートするオープン ソース/クロス プラットフォームの国際化ライブラリです。
このライブラリは、バージョン 64.1 から Microsoft Game Development Kit (GDK) 用に更新されました。 このライブラリを使用するには、ライブラリをビルド (readme の #HowToBuild を参照) してから、ゲームと共にパッケージ化します (readme の #HowToPackage を参照)。
注意
readme は GitHub には直接表示されません。 リポジトリをローカルに複製してビルドすると、ローカルでリポジトリを表示することができます。
以前のバージョンの Windows のサポート
19H1 より前の Windows ビルド (Windows 7 を含む) を対象とする場合は、レガシ コード ページの検出と変換を処理する必要があります。
マイクロソフトでは、コード ページの検出と変換の実行の必要性を排除する Win32 API の -Utf8 バリアントを提供するスタティック ヘルパー ライブラリの提供について、調査を続けています。 これにより、コンソール本体とWindows PC をターゲットとする共通のプログラミングサーフィスを Windows 7 まで提供することができます。