次の方法で共有


メタデータ API のコーディング規則

更新 : 2007 年 11 月

このトピックでは、メタデータ API で使用されるコーディング規則について説明します。

文字列パラメータの処理

メタデータ API は、すべての文字列を Unicode 形式で公開します。実際には、ディスク上のシンボル名形式は UTF-8 ですが、メタデータ API クライアントからは非表示です。返されるすべての文字列は次の 3 つのパラメータから成ります (実際のパラメータ名は異なります)。

  • [入力] ULONGcchString : 文字列 (終端の null 文字を含む) が返されるバッファのバイト単位によるサイズ。

  • [出力] LPCWSTRwzString : 文字列が返されるバッファへのポインタ。

  • [出力] ULONG *pchString : 返される文字列 (終端の null 文字を含む) のサイズへのポインタ。バッファが小さすぎてすべての文字列を格納できない場合、返される文字列は切り捨てられ、エラーが返されます。クライアントは必要に応じてバッファを再割り当てし、再試行できます。

シンボル名

次の規則は、文字列パラメータのシンボル名に適用されます。

  • シンボル名である文字列パラメータは必ず null で終わることが前提となっており、長さの [入力] パラメータは必要ありません。埋め込み null 文字はサポートされません。

  • [入力] パラメータ文字列が長すぎて切り捨てなしでは保持できない場合、エラーが返されます。

ユーザー文字列

次の規則は、ユーザー指定文字列パラメータに適用されます。

  • ユーザー文字列には、null 文字を埋め込むことができ、null 終端文字を含めることはできません。

  • 長さは、cchString パラメータに指定する必要があります。バッファのサイズは、格納される文字列の正確な長さにする必要があります。

既定値の格納

フィールド、パラメータ、およびプロパティの既定値として、定数をメタデータに格納できます。次の 3 つのパラメータを使用して定数を指定します (実際のパラメータ名は異なることがあります)。

  • [入力] DWORDdwCPlusTypeFlag - 既定値の型を指定する CorElementType 列挙型の値。

  • [入力] void const *pValue : 実際の既定値へのポインタ。たとえば、0x0000002A を保持する 4 バイトの DWORD へのポインタは、メタデータ内に 42 桁の DWORD 値を格納します。dwCPlusTypeFlag に指定される既定値の型は、プリミティブまたは文字列に限定されます。dwCPlusTypeFlag が ELEMENT_TYPE_CLASS である場合、既定値は null になります。

  • [入力] ULONGcchValue : pValue がポイントする Unicode 文字数 (バイト シーケンス単位)。これは、dwCPlusTypeFlag に指定されている型が ELEMENT_TYPE_STRING である場合のみ必須です。他の場合はすべて、長さは型から推論されます。

既定値は、初期化コードと静的に初期化されたデータ領域のいずれにも自動挿入されません。これらは、単純にメタデータ内に記録されます。

既定値を指定しない場合、dwCPlusTypeFlag のすべてのビットを設定します (値を -1 に設定します)。

戻り値を受け取るパラメータの null ポインタ

メタデータ API は最低限のエラー チェックを行うため、次の状況では戻り値を受け取るパラメータに非 null ポインタを想定しています。

  • Define メソッドでは、返されたトークンに対して非 null ポインタが必要です。これらのメソッドは、定義するアイテムを作成し、アイテムのトークンを返します。必要ない場合はトークンを破棄することを選択できます。

  • Find メソッドは、アイテムのトークンが正常に見つかった場合は常にそのトークンを返します。

  • Get メソッドでは、戻す必要がないパラメータ内に null を渡すことができます。

  • Set メソッドには、通常は戻り値がありません。トークン内に、更新する値と一緒に更新するアイテムを渡すと、メソッドが更新を実行します。

無視されるパラメータ値

メタデータ API のいくつかのメソッドでは、以前に定義したアイテムのプロパティを変更できます。次の例では、IMetaDataEmit::SetFieldProps メソッドを使用してフィールドのプロパティを変更します。プロパティは事前に IMetaDataEmit::DefineField への呼び出しで指定されていました。

HRESULT SetFieldProps(mdFieldDef fd, DWORD dwFieldFlags,
        DWORD dwDefType, void const *pValue, ULONG cchValue)

dwFieldFlags と pValue の一方のみを変更し、一方を変更しない場合があります。この場合、パラメータ値を変更しない場合でも、エラーを避けるためにパラメータ値を渡す必要があります。ただし、その値を変更しない場合、特定の値を渡すことにより、その引数を無視するように指定できます。メソッドの引数を無視する場合にメタデータ API は次の規則を使用します。

  • パラメータがポインタ型である場合、null ポインタを渡します。

  • パラメータが値型である場合 (通常はフラグ ビットマスク)、すべてのビットを設定する値 (–1) を渡します。

返されるエラー

IMetaDataDispenserExIMetaDataEmit、および IMetaDataImport の各インターフェイスでは、ほとんどすべてのメソッドが結果を示す HRESULT 値を返します。操作が成功した場合は、これは値 S_OK です。呼び出しがエラーになった場合は、操作が失敗した理由を説明する別の値が返されます。

すべてのメタデータ API で一般的なパターンとしては、呼び出し元が結果よりも小さい文字列バッファを指定すると、API はできるだけ多くの数の文字をコピーし、S_OK ではなく、CLDB_S_TRUNCATION の HRESULT 値を返します。

IMetadata インターフェイスの呼び出し元はコンパイラまたはツールです。エラーを検出するために、呼び出し元が各呼び出しのリターン ステータスを常にチェックすることが重要です。この場合、エラー条件はユーザー (アプリケーション プログラムなど) ではなく、直接の呼び出し元 (コンパイラなど) の問題を反映します。

メモリ管理

汎用 COM の既定では、呼び出し先が割り当てたメモリは呼び出し元が解放します。ただし、メタデータ メソッドの動作は異なります。

多くのメタデータ メソッドは、メモリのブロックに対する [出力] ポインタを返します。このようなメモリは、モジュールのメタデータ ヒープの一部であり、共通言語ランタイム (CLR: Common Language Runtime) によって所有されます。したがって、CLR が所有するメタデータのメモリ内ストレージを直接示すポインタを受け取るので、アプリケーションでメモリを解放する必要はありません。

ジェネリックのサポート

.NET Framework Version 2.0 では、メタデータ API は大幅に拡張され、ジェネリック (別名 "パラメータ ポリモーフィズム") をサポートしています。ジェネリックは C++ のテンプレートに似ています。次の例は、C# でジェネリック クラスを定義しています。

public class Dictionary<Key, Val> { . . . }

この場合、Dictionary クラスは Key と Val という 2 つのジェネリック パラメータを使用してパラメータ化されています。このクラスをインスタンス化する場合、次の例のようにジェネリック パラメータの型を選択します。

Dictionary<string, int> NameToPhone = new Dictionary<string, int>();
Dictionary<int, string> PhoneToName = new Dictionary<int, string>();

参照

その他の技術情報

メタデータの概要