Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

プロキシ・クラスの生成

プロキシ・クラスは、Caché クラスの定義を読み取り、その情報を使用して対応する C++ クラスを生成する、Caché C++ クラス・ジェネレータによって生成されます ("C++ ジェネレータの使用法" を参照してください)。生成されたクラスは、C++ アプリケーションから Caché オブジェクトのインスタンスへのリモート・アクセスを提供します。

概要

C++ ジェネレータは、対応する Caché クラスと同じ継承階層を持つ C++ プロキシ・クラスを生成します。クラスのタイプ (永続、シリアルなど) によって、それに対応する C++ スーパークラスが決まります。例えば、永続クラスは、Caché C++ ライブラリに含まれる C++ Persistent_t クラスから派生した、対応する C++ クラスを持ちます。多重継承の場合、クラスは Caché の最初のスーパークラスのサブクラスになり、他の直接スーパークラスからのすべてのメソッドとプロパティは、そのプロキシ・クラスのメンバとして生成されます。

Caché C++ クラス・ライブラリには、%PersistentOpens in a new tab%RegisteredObjectOpens in a new tab%SerialObjectOpens in a new tab、各種 Caché コレクション・クラス、およびさまざまなデータ型クラスの C++ バージョンなど、Caché クラス・ライブラリ内の C++ バージョンの多数のクラスが含まれています。さらに、このライブラリには C++ アプリケーション内で Caché サーバとの通信を管理するために使用する、さまざまなクラスが含まれます。

Note:

C++ バインディングでは、実行時、メタデータがコードの生成時以降に変更されたかどうかをチェックしません。具体的には、コード生成時と同じネームスペースにアプリケーションが接続されているかどうか、クラスが実行時のネームスペースに定義されているかどうかといったチェックがあります。これらが変更されていても、処理は継続され、データは挿入されますが、このデータには SQL やオブジェクト・インタフェースからはアクセスできません。

標準のプロキシ・クラス・メソッド

Caché クラスによって定義されるメソッドに加えて、すべての C++ プロキシ・クラスは、標準の Caché C++ ライブラリ・クラスである Persistent_t (永続クラスの場合) または Registered_t (シリアル・クラスの場合) から一連のメソッドを継承します。

C++ ジェネレータも、生成されたクラスに対して、一連の静的な Create および Open メソッドを追加します。C++ クラスの不正な使用を回避するため、プロキシ・クラスのコンストラクタはプライベートになっています。生成されたクラス T をインスタンス化する唯一の方法は、それぞれに d_ref<T> オブジェクトを返す、T::create_new()T::open()、または T::openid() のいずれかのスタティック・メソッドを呼び出すことです (詳細は、"プロキシ・オブジェクトの使用法" を参照してください)。これらのメソッドは、指定されたクラスに対応する Caché メソッドが存在する場合のみ生成されます。

スタティック・メソッドは以下のように定義されます (ここで、My_Class はプロキシ・クラスの名前です)。

  • create_new()%New メソッドを呼び出して、サーバ上にオブジェクトを生成します。

       static d_ref<My_Class> create_new(
          Database* db,
          const_str_t init_val = 0,    // const_str_t is a typedef of const wchar_t*
          Db_err* err = 0)
    
    
  • open() — 永続クラスに対してのみ生成されます。サーバ上で %Open を呼び出し、その完全なオブジェクト ID を使用してオブジェクトを開きます。

       static d_ref<My_Class> open(
          Database* db,
          const d_binary& ident,
          int concurrency = -1,
          int timeout = -1,
          Db_err* err = 0)
    
    
  • openid() — サーバ上で %Openid を呼び出し、そのエクステント固有の ID を使用してオブジェクトを開きます。

       static d_ref<My_Class> openid(
          Database* db,
          const const_str_t ident,    // const_str_t is a typedef of const wchar_t*
          int concurrency = -1,
          int timeout = -1,
          Db_err* err = 0)
    
    

プロキシ・メソッドの実装

Caché インスタンス・メソッドに対しては C++ インスタンス・メソッドが生成され、Caché クラス・メソッドに対しては C++ スタティック・メソッドが生成されます。C++ メソッドがクライアントで呼び出されると、Caché サーバ上にある実際のメソッドの実装が呼び出されます。メソッド・シグニチャに既定値の引数が含まれる場合、Caché は生成された C++ メソッド内でその既定値を使用します。例えば、1 つのメソッドを持つ単純な Caché クラスを定義するとします。

   Class MyApp.Simple Extends %RegisteredObject {
      Method LookupName(id As %String) As %String {
         // lookup a name using embedded SQL
         Set name = ""
         &sql(SELECT Name INTO :name FROM Person WHERE ID = :id)
         Quit name
      }
   }

得られる C++ クラス・ヘッダは以下のようになります。

   class MyApp_Simple : public Persistent_t {
      friend d_ref<MyApp_Simple>;
      public:
      // code
      virtual d_string LookupName(d_string id);
   }

メソッドが C++ から呼び出されると、C++ クライアントはまずサーバ・オブジェクト・キャッシュを同期化し、Caché サーバのメソッドを呼び出し、結果の値が存在する場合は最後にそれを返します。メソッドの引数が参照渡しで指定されている場合は、その値も更新されます。

プロキシ・プロパティの実装

C++ プロキシ・クラスのプロパティは、1 組みのアクセサ・メソッドを介してアクセスされます。各プロパティには、値の取得に使用する get<Property>() メソッドと、値の設定に使用する set<Property>() メソッドがそれぞれ対応付けられます。

(文字列や整数などの) リテラル・プロパティの値は、Caché C++ クラス・ライブラリによって提供される適切な C++ データ型クラス (d_stringd_int など) を使用して表されます。

オブジェクト値のプロパティの値は、d_ref テンプレート・クラスを使用して表されます ("プロキシ・オブジェクトの使用法" を参照してください)。

例えば、リテラルとオブジェクト値の 2 つのプロパティを持つ Caché に、永続クラスを定義したと仮定します。

   Class MyApp.Student Extends %Persistent {
      // Student's name
      Property Name As %String;
      // Reference to a school object
      Property School As School;
   }

MyApp.Student の C++ コードには、Name プロパティと School プロパティの両方に get と set の アクセサ・メソッドが含まれます。さらに、参照されている School オブジェクトのオブジェクト ID に対するアクセサも提供されます。

例えば、Caché のサンプル・クラスの Sample.Person では、DOB プロパティが以下のように定義されています。

   Property DOB As %Date(POPSPEC = "Date()");

POPSPEC のコンテンツは、サンプル・データでクラスを生成するためのものであり、実際のアプリケーションには表されません。Sample.PersonOpens in a new tab の C++ アクセサ・メソッドは以下のようになります。

   virtual d_date getDOB() const;
   virtual void setDOB(const d_date&);

C++ オブジェクトが C++ 内でインスタンス化されると、Caché サーバからそのプロパティ値のコピーをフェッチし、ローカル・クライアント側のキャッシュにそれらをコピーします。それ以降は、オブジェクトのプロパティ値へのアクセスはこのキャッシュに対して行い、サーバとの間で送信および受信するメッセージ数を減らします。Caché は自動的にこのローカル・キャッシュを管理し、Caché サーバで対応するオブジェクトの状態と確実に同期をとるようにします。

(他のプロパティに値を依存するプロパティを作成するなどの目的で) Caché クラス定義内で Get メソッドまたは Set メソッドが定義されたプロパティ値は、ローカル・キャッシュには格納されません。代わりに、そのようなプロパティにアクセスすると、対応するアクセサ・メソッドが Caché サーバで呼び出されます。これには、多量のネットワーク・トラフィックが必要となるため、クライアント/サーバ環境でこのようなプロパティを使用する場合、注意する必要があります。

名前付け規約

通常、クラス、メソッド、または変数の名前など、生成された C++ 識別子は、対応する Caché 識別子の名前と同じです。このセクションでは、そのルールの例外について説明します。

Note:

重要な点は、C++ 識別子に使用できる文字は、ObjectScript とは異なり、A ~ Za ~ z1 ~ 9、および "_" (アンダースコア) のみであることです。C++ では許可されていない文字を Caché 識別子で使用していると、これらの文字はアンダースコアに置き換えられます。Caché 識別子を高位 Unicode 文字で作成すると、アンダースコアのみで構成した C++ 識別子が発生する場合があります。以下で説明するように、代わりのクラス名とパッケージ名を Caché で定義できます。

  • クラス名とパッケージ名

    C++ はパッケージをサポートしていないため、クラスの Caché パッケージ名は、C++ クラス名の最初に "." 文字の代わりに "_" 文字を付けて表されます。クラス名自体は変わりません。

    Caché コードでパッケージ・クライアント名とクラスの ClientName パラメータの両方を定義している場合、Caché C++ ジェネレータでは、そのクラス名とパッケージ名ではなく、これらのパラメータを使用します。パッケージ名を設定するには、スタジオでパッケージ名を右クリックし、コンテキスト・メニューの [パッケージ情報] を選択して [クライアント名] フィールドに値を入力します。クラスの ClientName パラメータは、クラス・インスペクタを使用して定義できます。

  • メソッド名

    通常、メソッド名は変更されずに直接 C++ メソッドにマップされます。ただし、以下の例外があります。

    • メソッド名が "%" で始まる場合、"sys_" に置換されます。

    • メソッド名が C++ の予約語の場合、その名前の前に "_" が付きます。

  • プロパティ名

    サーバ上では、直接 Caché オブジェクトのプロパティを参照できます。C++ のプロパティの振る舞いをカプセル化するために、Caché の各プロパティに対して、2 つの C++ アクセサ・メソッドが生成されます。指定された Prop プロパティについては、getProp()setProp() というアクセサ・メソッドが生成されます。プロパティ名が "%" で始まる場合は、"sys_" に置き換わります。したがって、Color プロパティのアクセサ・メソッドは getColor()setColor() になり、%Concurrency プロパティのアクセサ・メソッドは get_sys_Concurrency()set_sys_Concurrency() になります。

  • 仮変数名

    メソッドの仮リスト内の変数が "%" で始まる場合、"_" に変換されます。その名前が予約語の場合、名前の前に "_" が付きます。

Caché Basic および ObjectScript の名前付け規約の詳細は、"Caché ObjectScript の使用法" の "変数"、"Caché オブジェクトの使用法" の "名前付け規約"、"Caché Basic の使用法" の "識別子と変数"、および "Caché プログラミング入門ガイド" の "識別子のルールとガイドライン" を参照してください。

C++ ジェネレータの使用法

Caché C++ ジェネレータは、Caché クラス定義から C++ クラスとヘッダ・ファイルを生成するプログラムです。コマンド行プログラム、またはスタジオのオプションとして使用できます。レベル 3 ("ロック・ダウン") セキュリティで Caché がインストールされている場合、ジェネレータを実行するには、%Service_Bindings を有効にする必要があります。

スタジオからジェネレータにアクセスするには、メイン・メニューから [ツール]→[C++ プロジェクションの生成] を選択します。このオプションでは、-lc パラメータと共にコマンド行プログラムを使用する必要がある、Light C++ バインディングのプロジェクションの生成は許可されません。

コマンド行プログラム cpp_generator.exe<cachesys>\dev\cpp\lib ディレクトリにインストールされますが、このディレクトリが各自の Path で指定されている必要があります(ご使用のシステムの <cachesys> の場所については、"Caché インストール・ガイド" の "Caché の既定のインストール・ディレクトリ" を参照してください)。

プログラムの構文は、以下のとおりです。

   cpp_generator 
   -conn <conn>
   -user <user>
   -pswd <password>
   -path <path>
   [-class <class>] | [-class-list <filename>]
   [-lc]
   [-help]

以下はその例です。

   cpp_generator 
   -conn "localhost[1972]:SAMPLES"
   -user "MyUserName"
   -pswd "MyPassword"
   -path "./cppfiles"
   -class "Sample.Person"
   -lc

C++ ジェネレータのパラメータ

-conn

<host>[<port>]:<namespace> 形式の接続文字列。

以下はその例です。 -conn "localhost[1972]:SAMPLES"

-user

ユーザ名を指定する文字列。

-pswd

パスワードを指定する文字列。

-class

または

-class-list

クラス名か、クラス名のリストを含むファイルのどちらか。

-class <class> オプションは、Caché サーバ・クラスの名前を指定します。以下はその例です。

-class "Sample.Person"

-class-list <filename> オプションは、Caché サーバ・クラスの名前を表す文字列のみが 1 行に 1 つずつ記述されたファイルの名前を指定します。以下はその例です。

-class-list "\Mydir\classlist.txt"

この classlist.txt には、以下の行が記述されています。

Sample.Person

Sample.Company

-path

生成される C++ クラスを配置するディレクトリを指定する文字列。

-lc オプション。-lc スイッチを使用すると、ジェネレータは Light C++ バインディング・クラスを生成します。
-help オプション。C++ ジェネレータのパラメータ・リストを表示します。

C++ ジェネレータは、指定されたクラスの実装に必要な他のすべてのクラスのコードを自動的に生成します。例えば、-class "Sample.Employee" を指定すると、Sample.PersonOpens in a new tab クラスと Sample.AddressOpens in a new tab クラスのコードも生成されます。これは、Sample.EmployeeOpens in a new tabSample.PersonOpens in a new tab から派生し、Sample.PersonOpens in a new tabSample.AddressOpens in a new tab 型のプロパティを持つためです。

FeedbackOpens in a new tab