__declspec キーワード拡張

提供: RAD Studio
移動先: 案内検索

Delphi データ型および言語概念のサポート への移動


拡張キーワード __declspec へのいくつかの引数により、ライブラリが言語的にサポートされています。これらの引数を以下に列挙します。__declspec の引数とそれらの組み合わせのマクロが sysmac.h に定義されています。ほとんど場合、これらを指定する必要はありません。どうしてもそれらを追加する必要がある場合は、これらのマクロを使用してください。

__declspec(delphiclass)

delphiclass 引数は、TObject から派生するクラスの宣言に使用します。これらのクラスは以下の互換性を持つように作成されています。

  • Object Pascal 互換の RTTI
  • ライブラリ互換のコンストラクタ/デストラクタの動作
  • ライブラリ互換の例外処理

ライブラリ互換クラスには次のような制限があります。

  • 仮想基底クラスは使用できません。
  • 継承とインターフェイス」で説明した場合を除き、多重継承は使用できません。
  • グローバル演算子 new を使って動的に割り当てる必要があります。

    メモ: インスタンスが静的に割り当てられている場合(ローカル変数としてなど)、declspec 指令はコンパイラで無視され、警告も出力されません。

  • デストラクタが必要です。
  • ライブラリから派生したクラスについては、コピー コンストラクタおよび代入演算子はコンパイラで自動生成されません。
  • TObject から派生したクラスであることをコンパイラが認識している必要がある場合は、Object Pascal から変換されたクラス宣言でこの修飾子が必要です。

__declspec(delphirecord)

delphirecord 記憶クラス属性は、(Delphi コンパイラdcc32 -JPHNE <ファイル名>.pas を使用して)Delphi レコードを .hpp ヘッダー内の C++ クラス/構造体に変換する場合に使用します。Delphi では、関数から返されるレコードについての規約があります。それは、レコードを返す関数は、返すべきレコードを指す hidden パラメータを返すという規約です。Delphi では、0 で初期化された場所を指すポインタが返りますが、C++ ではそのような保証はありません。これに準拠するために、C++ では、関数から返された構造体で、__declspec(delphirecord) フラグが付いているものを検出した場合は、そのメモリ領域を 0 にします。

__declspec(delphireturn)

delphireturn 引数は、C++Builder においてライブラリで内部的にのみ使用されるものです。これは C++Builder で作成されたクラスの宣言に使用され、Object Pascal の組み込みのデータ型および言語構文要素をサポートするように指定します(これらに相当するネイティブ C++ 型がないため)。それらの中には、Currency、UnicodeString、AnsiString、Variant、TDateTime、Set などがあります。delphireturn 引数は、C++ クラスで関数呼び出し時にパラメータと戻り値に関してライブラリ互換の処理が行われるように指定します。この修飾子が必要になるのは、Object Pascal と C++ の間で、構造体を関数に値渡しする場合です。

__declspec(delphirtti)

delphirtti 引数を指定すると、コンパイラはクラスのコンパイル時に実行時型情報をクラスに組み込みます。この修飾子を使用すると、コンパイラは、published セクションに宣言されているすべてのフィールド、メソッド、プロパティの実行時型情報を生成します。たとえば、コンパイラは、インターフェイスの全メソッドの実行時型情報を生成します。クラスのコンパイル時に実行時型情報も一緒に生成される場合、そのすべての下位クラスにも実行時型情報が組み込まれます。つまり、たとえば、クラス TPersistent のコンパイル時には実行時型情報も一緒に生成されるので、TPersistent を上位クラスとするクラスを作成する場合は、この修飾子を使用する必要がないということです。この修飾子は、Web サービスを実装または使用するアプリケーションに含まれているインターフェイスに主に使用されます。

__declspec(dynamic)

dynamic 引数は動的関数の宣言に使用されます。動的関数は仮想関数と似ていますが、下位クラス オブジェクトの仮想関数テーブル(vtable)ではなく定義元のオブジェクトの vtable にのみ格納される点が異なります。動的関数を呼び出すと、その関数がオブジェクトに定義されていなければ、関数が見つかるまで上位クラス オブジェクトの vtable が調べられます。動的関数は、TObject から派生するクラスにのみ有効です。

__declspec(hidesbase)

hidesbase 引数を指定すると、Object Pascal の仮想関数やオーバーライド関数を C++Builder に移植したときに、Object Pascal プログラムのセマンティクスが保たれます。Object Pascal では、基底クラスの仮想関数と同じ名前の関数が派生クラスに現れることがありますが、その場合は、基底クラスのものと明白な関係のないまったく新しい関数を意図しています。

コンパイラでは、sysmac.h に定義されている HIDESBASE マクロを使用して、この種の関数宣言がまったく別個のものであることを指定します。たとえば、引数のない仮想関数 func が基底クラス T1 に宣言されていて、その派生クラス T2 に同じ名前とシグネチャの関数が宣言されている場合、Delphi コンパイラ DCC32 - jphn を実行すると、以下のプロトタイプの HPP ファイルが生成されます。

    virtual void T1::func(void) ;
    HIDESBASE void T2::func(void) ;

HIDESBASE 宣言がなければ、C++ プログラムのセマンティクスでは、仮想関数 T1::func() が T2::func() でオーバーライドされることを示しています。

__declspec(package)

package 引数は、クラスを定義するコードをパッケージ内にコンパイルできることを示します。この修飾子は、IDE でパッケージを作成する際にコンパイラにより自動生成されます。

__declspec(pascalimplementation)

pascalimplementation 引数は、クラスを定義するコードが Object Pascal で実装されたことを示します。この修飾子は、Object Pascal の移植性のために用意されているヘッダー ファイル(拡張子は .hpp)で使用されます。

__declspec(uuid)

uuid 引数は、クラスにグローバル一意識別子(GUID)を関連付けるためのものです。これは任意のクラスで使用できますが、通常は、Object Pascal インターフェイス(または COM インターフェイス)を表すクラスで使用されます。__uuidof 指令を呼び出すことで、この修飾子を使って宣言されたクラスの GUID を取得できます。

関連項目