リソース識別子の記号名は、既定ではヘッダー ファイルResource.hで定義されます。ソース コードとリソース スクリプトでは、記号名はプリプロセッサによってそれぞれの数値に置き換えられます。コンパイルが開始されると、シンボリック情報はすでに失われています。
構成にシンボリック名を使用するスキームを実装するには、シンボリック名とリソース識別子の間のマッピングを抽出して保存し、後で実行時に使用するか、展開前に構成ファイルにマッピングを適用する必要があります。以下は、可能なオプションのリストです。
連想コンテナを使用し、アプリケーションの起動時に設定します:適切なコンテナはstd::map<std::string, unsigned int>
. このコンテナーへのデータの取り込みは、C++11 のリスト初期化機能を使用して簡単に実行できます。
static std::map<std::string, unsigned int> IdMap = {
{"ID_FILE_NEW", ID_FILE_NEW},
{"ID_FILE_OPEN", ID_FILE_OPEN},
// ...
}
実行時に、このコンテナーを使用して、指定されたシンボリック定数のリソース識別子を取得できます。
unsigned int GetId(const std::string& name) {
if (IdMap.find(name) == IdMap.end())
throw std::runtime_error("Unknown resource identifier.");
return IdMap[name];
}
このアプローチの欠点はIdMap
、リソースの同期を維持する必要があることです。リソースが追加、変更、または削除されるたびに、行われた変更を考慮してコンテナーの内容を更新する必要があります。
Resource.hを解析してマッピングを保存します。シンボリック識別子名を含むヘッダー ファイルの構造はかなり単純です。記号定数を定義するコード行は、通常、次のレイアウトになります。
\s* '#' \s* 'define' \s+ <name> \s+ <value> <comment>?
マッピングを抽出するパーサーは、見た目ほど実装が難しくなく、ビルド プロセスの適切なタイミングで実行する必要があります。マッピングが抽出されると、 INI ファイルなどの任意の形式のファイルに保存できます。このファイルは、アプリケーションと共にデプロイすることも、リソースとしてバイナリ イメージにコンパイルすることもできます。アプリケーションの起動時にコンテンツが読み戻され、前の段落で説明したようにマッピングを構築するために使用されます。前のソリューションとは対照的に、Resource.hファイルの解析では、リソースが変更されたときにコードを手動で更新する必要はありません。
Resource.hを解析して構成 XML ファイルを変換する:前のソリューションと同様に、このオプションでもResource.hファイルの解析が必要です。この情報を使用して、構成 XML ファイルを変換し、展開前に対応する数値を記号名に置き換えます。これも追加の作業が必要です。ただし、これが完了したら、プロセスを自動化し、結果を検証して一貫性を維持することができます。実行時に XML を読み取るだけで、数値識別子をすぐに利用できます。