Caché コールアウト・ゲートウェ イの使用法 Version 2014.1 2014 年 06 月 24 日 InterSystems Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com Caché コールアウト・ゲートウェイの使用法 Caché Version 2014.1 2014 年 06 月 24 日 Copyright © 2014 InterSystems Corporation All rights reserved. このドキュメントは、 Oracle Corporation、RenderX Inc.、 アドビ システムズ および ワールドワイド・ウェブ・コンソーシアム(www.w3c.org)のツールと 情報を使用して、 Adobe Portable Document Format (PDF)で作成およびフォーマットされました。主要ドキュメント開発ツールは、InterSystemsが構 築したCacheéと Javaを使用した特別目的のXML処理アプリケーションです。 , , , , Caché WEBLINK, および Distributed Cache Protocol は InterSystems Corporation の登録商標です。 and , InterSystems TrakCare, InterSystems Jalapeño Technology, Enterprise Cache Protocol, ECP および InterSystems Zen は InterSystems Corporation の 登録商標です。 ここで使われている他の全てのブランドまたは製品名は、各社および各組織の商標または登録商標です。 このドキュメントは、インターシステムズ社(住所:One Memorial Drive, Cambridge, MA 02142)あるいはその子会社が所有する企業秘密および秘密 情報を含んでおり、インターシステムズ社の製品を稼動および維持するためにのみ提供される。この発行物のいかなる部分も他の目的のために使 用してはならない。また、インターシステムズ社の書面による事前の同意がない限り、本発行物を、いかなる形式、いかなる手段で、その全てまたは 一部を、再発行、複製、開示、送付、検索可能なシステムへの保存、あるいは人またはコンピュータ言語への翻訳はしてはならない。 かかるプログラムと関連ドキュメントについて書かれているインターシステムズ社の標準ライセンス契約に記載されている範囲を除き、ここに記載さ れた本ドキュメントとソフトウェアプログラムの複製、使用、廃棄は禁じられている。インターシステムズ社は、ソフトウェアライセンス契約に記載され ている事項以外にかかるソフトウェアプログラムに関する説明と保証をするものではない。さらに、かかるソフトウェアに関する、あるいはかかるソフ トウェアの使用から起こるいかなる損失、損害に対するインターシステムズ社の責任は、ソフトウェアライセンス契約にある事項に制限される。 前述は、そのコンピュータソフトウェアの使用およびそれによって起こるインターシステムズ社の責任の範囲、制限に関する一般的な概略である。完 全な参照情報は、インターシステムズ社の標準ライセンス契約に記され、そのコピーは要望によって入手することができる。 インターシステムズ社は、本ドキュメントにある誤りに対する責任を放棄する。また、インターシステムズ社は、独自の裁量にて事前通知なしに、本ド キュメントに記載された製品および実行に対する代替と変更を行う権利を有する。 インターシステムズ社の製品に関するサポートやご質問は、以下にお問い合わせください: Tel: Fax: Email: InterSystems Worldwide Customer Support +1 617 621-0700 +1 617 374-9391 [email protected] 目次 このドキュメントについて ................................................................................................... 1 1 はじめに ..................................................................................................................... 3 1.1 コールアウト・ゲートウェイの概念および用語 ............................................................. 3 1.2 $ZF 関数の概要 .................................................................................................. 4 1.3 互換性のある言語とコンパイラ ................................................................................ 5 2 オペレーティング・システム・コマンドの発行 ....................................................................... 7 2.1 $ZF(-1) を使用したシステム・コマンドの発行 ............................................................. 7 2.1.1 OpenVMS デバイス・パラメータの使用 ............................................................. 8 2.2 ZF(-2) を使用した同時子プロセスの作成 ................................................................. 9 2.3 %System_Callout:USE 特権の追加 ........................................................................... 9 2.3.1 ユーザへのロールの割り当て ........................................................................ 9 2.3.2 新規ロールの作成 ..................................................................................... 10 3 Caché コールアウト・ライブラリの作成 .............................................................................. 11 3.1 コールアウト・ライブラリの概要 ............................................................................... 11 3.1.1 ZFEntry テーブルの作成 ............................................................................ 13 3.2 ZFEntry リンク・オプション .................................................................................... 14 3.2.1 リンクの概要 .............................................................................................. 14 3.2.2 数値リンクの使用 ....................................................................................... 15 3.2.3 NULL で終了する文字列を C リンク・タイプで渡す .......................................... 16 3.2.4 計算文字列を B リンク・タイプで渡す ............................................................ 17 3.2.5 Caché の長い文字列を J リンク・タイプで渡す ................................................. 18 3.2.6 $ZF ヒープの構成 ...................................................................................... 20 3.3 コールアウト・ライブラリの Runup 関数と Rundown 関数 ............................................. 20 3.4 トラブルシューティング ......................................................................................... 21 4 コールアウト・ライブラリ関数の呼び出し ........................................................................... 23 4.1 コールアウト・ライブラリのインタフェース .................................................................. 23 4.2 単純なライブラリ関数呼び出しでの $ZF(-3) の使用 ................................................. 24 4.3 システム ID によるライブラリへのアクセスでの $ZF(-5) の使用 ................................... 25 4.4 ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 ......................... 27 4.4.1 ライブラリ関数のカプセル化での $ZF(-6) インタフェースの使用 ......................... 29 4.4.2 テストでのプロセス・インデックスの使用 .......................................................... 31 5 静的にリンクされたコールアウト関数 ............................................................................... 33 5.1 静的にリンクされたコールアウト関数の呼び出し ....................................................... 33 5.2 Windows でのカスタム CACHE.EXE ファイルの作成 ................................................ 34 5.3 UNIX®、Linux、または OS-X でのカスタム CACHE.EXE ファイルの作成 ..................... 35 5.4 OpenVMS でのカスタム CZF.EXE ファイルの作成 ................................................... 36 6 UNIX® に関する特別な考慮事項 .................................................................................. 39 6.1 その他のコールアウト・シグナル処理 ..................................................................... 39 7 OpenVMS に関する特別な考慮事項 .............................................................................. 41 7.1 CZF.M64 の使用 ............................................................................................... 41 7.2 特権レベルを上げる ZFPRIV の使用 ..................................................................... 42 7.3 71 システム・サービスでの V リンクの使用 .............................................................. 42 7.4 DSM に代わる $ZF 関数呼び出し ......................................................................... 43 7.4.1 $ZF 内部関数 ........................................................................................... 44 Caché コールアウト・ゲートウェイの使用法 iii 8 Caché コールアウトのクイック・リファレンス ........................................................................ 53 8.1 静的にリンクされた関数の使用 ............................................................................. 54 8.2 プログラムまたはシステム・コマンドの実行 ............................................................... 54 8.3 インデックスなしのコールアウト・ライブラリの使用 ...................................................... 55 8.4 インデックス付きのコールアウト・ライブラリの使用 ..................................................... 57 iv Caché コールアウト・ゲートウェイの使用法 このドキュメントについて Caché コールアウト・ゲートウェイ (Caché $ZF 関数に実装されている) を使用すると、外部プログラムおよびシステム・ サービスを Caché から呼び出すことができます。また、カスタム・コードを Caché に統合する方法も提供します。 このドキュメントでは、以下の項目について説明します。 • はじめに — Caché コールアウト・ゲートウェイの機能についてまとめ、サンプルおよびその他のリソースへのリンクを 提供します。 • オペレーティング・システム・コマンドの発行 — オペレーティング・システム・コマンドおよびサービスへのアクセスに 使用できる子プロセスを生成する方法を説明します。 • Caché コールアウト・ライブラリの作成 — Caché から呼び出すことができる関数を備えたコールアウト共有ライブラリ の作成方法を説明します。コードは、C/C++ 呼び出し規則をサポートする任意の言語で記述できます。 • コールアウト・ライブラリ関数の呼び出し — コールアウト共有ライブラリから関数を動的に呼び出す方法を説明しま す。 • 静的にリンクされたコールアウト関数 — コールアウト関数を含むカスタマイズ・バージョンの Caché を作成する方法 を説明します。 • UNIX® に関する特別な考慮事項 — UNIX® および関連するオペレーティング・システムのみに関する問題につい て説明します。 • OpenVMS に関する特別な考慮事項 — OpenVMS のみに関する問題について説明します。 • Caché コールアウトのクイック・リファレンス — 各 $ZF 関数の詳細な説明を提供します。 詳細は、目次 を参照してください。 一般的な情報については、InterSystems のドキュメントの使用法 を参照してください。 Caché コールアウト・ゲートウェイの使用法 1 1 はじめに Caché コールアウト・ゲートウェイを使用すると、Caché アプリケーションがシェルまたはオペレーティング・システム・コマ ンドを呼び出し、生成されたプロセスで外部プログラムを実行し、特別に記述された共有ライブラリから関数を呼び出す ことができます。コールアウト・ゲートウェイは、Caché $ZF システム関数内に含まれる一連の関連した関数として実装さ れます。 以下の項目について説明します。 • コールアウト・ゲートウェイの概念および用語 — このドキュメントの以降の部分を読む前に知っておくべき事柄のリス トです。 • $ZF 関数の概要 — コールアウト・ゲートウェイによって提供される機能の概要を説明します。 • 互換性のある言語とコンパイラ — コールアウト・ゲートウェイの利点を最大限に活用するために必要ないくつかのソ フトウェアについて説明します。 1.1 コールアウト・ゲートウェイの概念および用語 このドキュメントの以降の部分を読む前に理解しておく必要がある重要な概念について説明します。 個々の $ZF 関数の識別 $ZF スイート内の個々の関数は、関数呼び出しの最初の引数によって識別されます。これは -1 ~ -6 の負の 数字です。例えば、オペレーティング・システム・コマンドを呼び出す関数は $ZF(-1, <oscommand>) の形 式を持ちます。ここで、<oscommand> は、実行されるコマンドを含む文字列です。この関数について述べる場 合には、$ZF(-1) と示されます。同様に、その他の関数は、実際の関数呼び出しの最初のパラメータのみを使 用して $ZF(-2) ~ $ZF(-6) と示されます。 $ZF(-4) 関数は、実際は最初の 2 つのパラメータ $ZF(-4,1) ~ $ZF(-4,8) によって識別される 8 つのユーティ リティ関数のコンテナであるため、特殊なケースです。 これらの関数の概要については、この章で後述する “$ZF 関数の概要” を参照してください。すべての $ZF 関数の完全なリスト、それらの使用方法に関する情報、および詳細な情報および例へのリンクについては、 “Caché コールアウトのクイック・リファレンス” を参照してください。 コールアウト・ライブラリ このドキュメントでは、共有ライブラリという用語は、動的にリンクされたファイル (Windows の DLL ファイル、 UNIX® および関連オペレーティング・システムの SO ファイル、または OpenVMS の共有可能イメージ・ファイ ル) を示します。コールアウト・ライブラリは、コールアウト・ゲートウェイへのフックを含む共有ライブラリであり、多 Caché コールアウト・ゲートウェイの使用法 3 はじめに 様な $ZF 関数が実行時にロードして、その関数を呼び出すことができるようにします。コールアウト・ライブラリ は、通常は C で記述されますが (“互換性のある言語とコンパイラ” を参照)、ご使用の C コンパイラで認識さ れる呼び出し規則を使用するその他のコンパイル言語で記述される場合もあります。 コールアウト・ライブラリの記述方法の詳細は、“Caché コールアウト・ライブラリの作成” を参照してください。 コールアウト・ライブラリのインタフェース すべての $ZF 関数 ($ZF(-1) および $ZF(-2) を除く) は、コールアウト・ライブラリへのいくつかのアクセス形式 を提供するために使用されます。$ZF(-3)、$ZF(-5)、および $ZF(-6) 関数は、コールアウト・ライブラリ関数の呼 び出しに 3 つの異なるインタフェースを提供します。$ZF(-4) は、$ZF(-5) および$ZF(-6) インタフェースと一緒 に使用される多様なユーティリティ関数のコンテナです。 コールアウト・ライブラリへの多様なアクセス方法の詳細は、“コールアウト・ライブラリ関数の呼び出し” を参照 してください。 1.2 $ZF 関数の概要 $ZF 関数スイートには、以下の関数があります。 $ZF(-1) および $ZF(-2) 関数 $ZF(-1) および $ZF(-2) 関数は、シェル・コマンドおよびオペレーティング・システム・サービスの呼び出しの実 行に使用されます。これらは、コールアウト・ライブラリへのアクセスには使用されず、前の設定なしで呼び出す ことができます。 詳細は、“ オペレーティング・システム・コマンドの発行” を参照してください。 $ZF(-3) 関数 $ZF(-3) 関数は、コールアウト・ライブラリをロードして単一の文でライブラリ関数を呼び出す簡単な方法です。 ライブラリとその関数の両方が名前で指定され、ライブラリは異なるライブラリへの呼び出しによって置き換えら れるまでメモリ内に残ります。 詳細は、“ 単純なライブラリ関数呼び出しでの $ZF(-3) の使用” を参照してください。 $ZF(-4) 関数 $ZF(-4) 関数は、8 つのユーティリティ関数セットのコンテナです。$ZF(-5) 関数インタフェースは、関数 $ZF(-4,1) ~ $ZF(-4,3) を使用し、$ZF(-6) 関数インタフェースは、関数 $ZF(-4,5) ~ $ZF(-4,8) を使用します。詳細は、 以下の説明を参照してください。 $ZF(-5) 関数インタフェース $ZF(-5) 関数およびそのユーティリティ関数を使用すると、複数のライブラリを効率的に処理できます。ライブラ リおよびその関数の両方がシステム定義の ID 値によって識別されます。複数のライブラリを同時に仮想メモリ 内に入れることができます。以下の $ZF(-4) 関数はライブラリのロードやアンロード、およびライブラリや関数 ID 値の取得に使用されます。 • $ZF(-4,1) は、名前によって指定されるライブラリをロードし、ライブラリ ID を返します。 • $ZF(-4,2) は、ライブラリをアンロードします。 • $ZF(-4,3) は、指定されたライブラリ ID および関数名の関数 ID を返します。 詳細は、“ システム ID によるライブラリへのアクセスでの $ZF(-5) の使用” を参照してください。 4 Caché コールアウト・ゲートウェイの使用法 互換性のある言語とコンパイラ $ZF(-6) 関数インタフェース $ZF(-6) 関数およびそのユーティリティ関数は、ハードコード化されたライブラリ名を必要としないコールアウト・ アプリケーションを記述する方法を提供します。代わりに、実際のライブラリ・ファイル名は別のインデックス・テー ブルに含まれます。ここでは、各ライブラリは一意のユーザ定義インデックス番号に関連付けられています。イ ンデックス・テーブルが定義されると、Caché のインスタンス内のすべてのプロセスで利用可能になります。コー ルアウト・アプリケーションは、ライブラリをインデックス番号で識別し、インデックス・テーブルを読み取ることに よってロードします。複数のライブラリを同時にメモリ内に入れることができます。以下の関数は、インデックスの 管理とライブラリのロードまたはアンロードに使用されます。 • $ZF(-6) は、ライブラリ関数を呼び出し、ライブラリがまだメモリ内に無い場合には、ロードします。 • $ZF(-4,4) は、ライブラリをアンロードします。 • $ZF(-4,5) および $ZF(-4,6) は、Caché のインスタンス内のすべてのプロセスでアクセス可能なシステム・イ ンデックス・テーブルを作成および維持するために使用されます。 • $ZF(-4,7) および $ZF(-4,8) は、単一プロセス内のシステム・インデックスをオーバーライドするために使用 できるプロセス・インデックス・テーブルを作成および維持するために使用されます。 詳細は、“ ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” を参照してください。 $ZF() 関数 通常、C 関数コードは、コールアウト・ライブラリの生成に使用されますが、Caché 実行可能ファイルのカスタム・ バージョンに直接リンクすることもできます。$ZF() 関数 (負の数の引数なし) は、静的にリンクされたコールアウ ト関数を呼び出すためのインタフェースです。$ZF(-3)、$ZF(-5)、または $ZF(-6) とは異なり、外部ライブラリ識 別子を指定する必要はなく、静的にリンクされた関数は関数名および引数を指定するだけで呼び出すことがで きます。 詳細は、“ 静的にリンクされたコールアウト関数” を参照してください。 1.3 互換性のある言語とコンパイラ コールアウト・ゲートウェイを使用して、Caché ObjectScript 以外の言語で記述されたルーチンを呼び出すことができま す。Caché をサポートするすべてのプラットフォーム上で、C 言語で記述されたルーチンを呼び出すことができます。理 論上は、C と互換性がある任意のコンパイル言語で記述されたルーチンを呼び出すことができますが、2 つの互換性の 問題が発生します。1 つは、コンパイラは C と互換性があるアプリケーション・バイナリ・インタフェース (ABI) を使用する 必要があることです。2 つ目は、コンパイラは Caché と互換性がないランタイム・ライブラリ機能に依存しないコードを生 成する必要があることです。 インターシステムズは、すべてのプラットフォーム上で Caché を生成するために使用するのと同じ C コンパイラの使用を サポートします。 Caché コールアウト・ゲートウェイの使用法 5 はじめに プラットフォーム コンパイラ HP HP-UX 11 HP C/aC++ コンパイラ HP OpenVMS Alpha HP C HP Tru64 UNIX Compaq C IBM AIX AIX 用 IBM XL C Mac OS X (Darwin) Xcode Microsoft Windows Microsoft Visual Studio Oracle Solaris Sun C Linux (系列すべて) GNU プロジェクト GCC C ほとんどのプラットフォームは、標準化されたアプリケーション・バイナリ・インタフェース (ABI) を備え、ほとんどのコンパ イラに互換性があります。Intel x86-32 および x86-64 プラットフォームは主な例外であり、これらのプラットフォームには、 複数の呼び出し規則が存在します。これらのプラットフォームでの呼び出し規則については、 (http://en.wikipedia.org/wiki/X86_calling_conventions) を参照してください。 Microsoft Windows の場合、x86-32 プラットフォームでは cdecl インタフェース、x86-64 では (http://msdn.microsoft.com/ja-jp/library/9b372w95(v=vs.80).aspx) で記述されている呼び出し規則を使用します。 多くの C コンパイラでは別の呼び出し規則を使用する外部ルーチンの宣言を許可しているため、異なる呼び出し規則 を使用する言語を呼び出すことは可能です。したがって、C ラッパ・ルーチンを記述するのであれば、他の言語で記述 されたルーチンを呼び出すことができます。 OpenVMS では、すべてのコンパイラが OpenVMS Calling Standard (http://h71000.www7.hp.com/doc/82final/5973/5973pro.html) に従っています。 6 Caché コールアウト・ゲートウェイの使用法 2 オペレーティング・システム・コマンドの発行 Caché $ZF(-1) および $ZF(-2) 関数により、Caché からオペレーティング・システム・コマンドを発行できます。これらは、 特別なコールアウト共有ライブラリなしで使用できる Caché コールアウト関数です (“Caché コールアウト・ライブラリの作 成” を参照)。このセクションで説明する項目は以下のとおりです。 • $ZF(-1) を使用したシステム・コマンドの発行 — $ZF(-1) コマンドは、Windows の MS-DOS コマンド、UNIX® およ び Linux のシェル・コマンドとシステム・サービス、または OpenVMS の DCL コマンドとシステム・サービスを発行す るために使用します。 • $ZF(-2) を使用した同時子プロセスの作成 — $ZF(-2) の操作は、$ZF(-1) と基本的に同じですが、Caché が非同 期子プロセス内でシステム・コマンドを実行し、返りを待機しない点が異なります。 • %System_Callout:USE 特権の追加 — Caché セキュリティ設定が最低よりも高い場合は、$ZF(-1) および $ZF(-2) の 両方で %System_Callout:USE 特権が必要です。 2.1 $ZF(-1) を使用したシステム・コマンドの発行 $ZF(-1) は、ホスト・オペレーティング・システムのコマンドの呼び出しを許可します。指定されたコマンドは、現在のコン ソールから生成された子プロセスとして実行されます。$ZF(-1) は、子プロセスの終了を待機し、子プロセスの実行中は 親 Caché プロセスの終了を許可しません。 子プロセスが終了した後で、$ZF(-1) は、オペレーティング・システム・シェルによって発行された終了ステータス・エラー・ コードを返します。可能な値は、関数呼び出しが正常に実行された場合は 0、エラーが発生した場合は 1、子プロセス が生成されなかった場合は -1 です。 Windows Windows では、以下の ObjectScript コードによって test folder という名前のディレクトリが現在のディレクトリ内 に作成されます (名前にスペースが含まれるため、Windows ではディレクトリ名の前後に引用符を追加する必 要があります)。 SET status = $ZF(-1,"mkdir ""test folder""") UNIX® および Linux 以下の例では、pwd コマンドを実行しています。 SET status = $ZF(-1,"pwd") シェル・ウィンドウに次のような出力が表示されます。 Caché コールアウト・ゲートウェイの使用法 7 オペレーティング・システム・コマンドの発行 /usr/cachesys OpenVMS 以下の例では、DCL SHOW DEF コマンドを実行しています。 SET status = $ZF(-1,"SHOW DEF") シェル・ウィンドウに次のような出力が表示されます。 DUA0:[usr] DCL 呼び出しにいかなる特権レベルが必要であったとしても、呼び出しを実行するプロセスは、コマンドの完 了後、元の特権レベルに戻ります。 注釈 ほとんどの場合、$ZF(-1) はバックグラウンドで有効なコマンドでのみ使用する必要があります。コマンドがユー ザ入力を必要とする場合 (以下の例のようにユーザがメモ帳を終了することが必要)、子プロセスが停止します。 以下の例のコマンドでは、指定されたファイルを .txt ファイルの既定のアプリケーションで開きます。 $ZF(-1) を使用したテキスト・ファイルのオープン SET fname="""C:\My Test.txt""" WRITE fname,! SET status=$ZF(-1,fname) WRITE status /// NOTE: THIS EXAMPLE STARTS A PROCESS THAT WILL NOT RETURN UNTIL YOU /// CLOSE THE PROGRAM (USUALLY NOTEPAD) THAT OPENS THE TEXT FILE. • fname が定義されるとき、パス全体が二重引用符で囲まれています。これは、パスにスペースが含まれてい る場合に、Windows および UNIX® で必須です。OpenVMS の場合はパス名内のスペースに対して特別な 処理は要求されません。 • $ZF(-1,fname) への呼び出しでは、ファイルが .txt ファイルの既定のアプリケーションで開きます。Windows の場合、これは以下の MS-DOS コマンドを発行するのと同等です。 C:\>call "C:\My Test.txt" 既定では、このコマンドではメモ帳でファイルが開きます。子プロセスは、再びメモ帳が閉じられるまで返ら ず、$ZF(-1) は、メモ帳が開いている間は親 Caché プロセスの終了を許可しません。 • 注釈 status の返される値は、関数呼び出しが正常に実行された場合は 0、エラーが発生した場合 (例えば、 C:\My Test.txt が存在しない場合) は 1、子プロセスがフォークできない場合は -1 です。 Caché ターミナルでの $ZF(-1) の使用 $ZF(-1) は、インタラクティブなオペレーティング・システム・シェルを Caché ターミナルにロードするためにも使 用できます ("Caché ターミナルの使用法" の “オペレーティング・システム・シェル” を参照してください)。こ れは、! ターミナル・コマンドのように動作しますが、$ZF(-1) が別のウィンドウで実行される点が異なります。! は、すべてCaché ターミナル・ウィンドウ内で動作します。 2.1.1 OpenVMS デバイス・パラメータの使用 OpenVMS では、$ZF(-1) コマンドは以下のようにオプション・デバイスの入力および出力パラメータを使用できます。 SET status = $ZF(-1,DCLcommand[,outdev[,indev]]) ここで、子プロセスに対して outdev は SYS$OUTPUT を指定し、indev は SYS$INPUT を指定します。 8 Caché コールアウト・ゲートウェイの使用法 ZF(-2) を使用した同時子プロセスの作成 $ZF(-1) 発行時に生成された OpenVMS プロセスが強制終了あるいは停止された場合、返りコードは -1 になります。 親プロセスと同じ SYS$INPUT の使用を試みる子プロセスによってこの問題が発生する場合があります。これは、indev パラメータを指定することにより対処できます。OpenVMS エラー・コードは、SYSLOG ユーティリティを使用して表示でき ます。 2.2 ZF(-2) を使用した同時子プロセスの作成 $ZF(-2) は、指定されたプログラムを現在のコンソールから生成された子プロセスとして実行します。子プロセスを生成し たら直ちに返し、プロセスの終了を待機しません。入力と出力のデバイスは、NULL デバイスが既定になります。 注釈 $ZF(-2) 経由で実行されるコマンドは、主デバイスでの入出力を実行できません。通常、Caché では主デバイ スと NULL デバイスは同等です。 $ZF(-2) は子プロセスの終了状態を返しません。代わりに、子プロセスが正常に作成された場合はゼロを返し、子プロセ スをフォークできなかった場合には -1 を返します。$ZF(-2) は、Caché が終了された場合でも、Caché から呼び出され たプログラムの実行の継続を許可します。 $ZF(-2) は、コマンドを実行する前に親プロセスの主デバイス (Caché 特殊変数 $PRINCIPAL で指定) を終了します。 これは、子プロセスが親プロセスと同時に実行されるためです。$ZF(-2) が $PRINCIPAL を終了しなかった場合は、親 と子からの出力が混ざり合います。$ZF(-2) の使用時に、子プロセスからの出力を回復させる場合は、コマンドで入出力 をリダイレクトします。以下はその例です。 SET x=$ZF(-2,"ls -l > mydir.txt") progname で指定されたパス名にスペース文字が含まれる場合、パス名の処理はプラットフォームによって異なります。 OpenVMS の場合はパス名にスペースを使用でき、特別な処理は要求されません。UNIX® の場合はパス名にスペース 文字を使用することができますが、スペースを含むパス名は、二重引用符 (“) で囲む必要があります。Windows では、 スペースを削除するか、またはスペースを含むパス名を追加の引用符で囲むことが必要です。例えば、スペースがない 場合は、"C:\MyDocuments"、スペースがある場合は、""C:\My Documents"" となります。%Library.File クラスの NormalizeFilenameWithSpaces() メソッドを使用すると、パス名内のスペースがホスト・プラットフォームに合わせて処理さ れるようにできます。 2.3 %System_Callout:USE 特権の追加 Caché セキュリティ設定が最低よりも高い場合は、$ZF(-1) および $ZF(-2) の両方で %System_Callout:USE 特権が 必要です。 %System_CallOut リソースは、Caché のインストール時に開発者設定を選択した場合に持つ %Developer ロールに 既に割り当てられています。以下のセクションは、まだこのリソースを持っていない場合に、これを割り当てる方法を説明 します。 • ユーザへのロールの割り当て — %Developer ロールをユーザに割り当てる方法を説明します。 • 新規ロールの作成 — %System_CallOut:USE 特権のみを付与する新規ロールを作成する方法を説明します。 2.3.1 ユーザへのロールの割り当て 以下の手順を使用して、%Developer ロールを割り当てます。 Caché コールアウト・ゲートウェイの使用法 9 オペレーティング・システム・コマンドの発行 1. SMP を開き、[システム管理] > [セキュリティ管理] > [ユーザ] に移動して、使用するユーザ説明上で [編集] をクリッ クし、[ロール] タブを選択します。 2. %Developer ロールを [使用可能] 列から [選択済み] 列に移動して [割り当てる] をクリックします。このユーザに 割り当てるロールのリストにロールが表示されます (%Developer ロールが [使用可能] 列に表示されない場合は、 ロールのリストをチェックして、既にこのロールを持っているかどうかを確認します)。 3. [プロファイル] ボタンをクリックします。%Developer ロールが [ロール:] 行にリストされます。 2.3.2 新規ロールの作成 $ZF(-1) および $ZF(-2) の使用を許可するが、その他の特権を付与しないロールを持つことが望ましい場合があります。 以下の手順を使用して、%System_CallOut:USE 特権のみを付与する新規ロールを作成します。 1. SMP を開き、[システム管理] > [セキュリティ管理] > [ロール] に移動します。 2. [新規ロール作成] ボタンをクリックして、[ロール編集] ページを開きます。 3. 以下のように名前と説明を入力します。 • 名前: UseCallout • 説明: %System_CallOut [保存] をクリックすると、フォームに [追加] ボタンが表示されます。 4. [追加] ボタンをクリックすると、リソースのスクロール・リストが表示されます。リストから %System_CallOut を選択し て [保存] をクリックします。[ロール編集] フォームの [閉じる] をクリックします。 5. [ロール] ページのロール定義のリストに新しい UseCallout ロールが表示されます。 10 Caché コールアウト・ゲートウェイの使用法 3 Caché コールアウト・ライブラリの作成 Caché コールアウト・ライブラリは、カスタム・コールアウト関数、および Caché がそれらを使用できるようにする使用可能 化コードを含む共有ライブラリです。この章では、コールアウト・ライブラリを作成して実行時にアクセスする方法を説明し ます。 以下の項目について説明します。 • コールアウト・ライブラリの概要 — コールアウト・ライブラリの作成およびアクセス方法を説明します。 • ZFEntry リンク・オプション — 関数引数が渡される方法を決定するリンク・オプションの詳細を説明します。 • コールアウト・ライブラリ Runup 関数と Rundown 関数 — コールアウト・ライブラリがロードまたはアンロードされるとき に自動的に呼び出される 2 つのオプション関数について説明します。 • トラブルシューティング — 避けるべきコーディング作業について説明します。 注釈 共有ライブラリとコールアウト・ライブラリ このドキュメントでは、共有ライブラリという用語は、動的にリンクされたファイル (Windows の DLL ファイル、 UNIX® および関連オペレーティング・システムの SO ファイル、または OpenVMS の共有可能イメージ・ファイ ル) を示します。コールアウト・ライブラリは、コールアウト・ゲートウェイへのフックを含む共有ライブラリであり、 多様な $ZF 関数が実行時にこれをロードし、アクセスできるようにします。 3.1 コールアウト・ライブラリの概要 Caché ObjectScript コードからコールアウト・ライブラリにアクセスするには複数の方法がありますが、一般的には、ライブ ラリ名、関数名、および必要な引数を指定するのが主な方法です (“コールアウト・ライブラリ関数の呼び出し” を参照)。 例えば、以下のコードでは、簡単なコールアウト・ライブラリ関数を呼び出します。 コールアウト・ライブラリ simplecallout.dll からの関数 AddInt の呼び出し 以下の ObjectScript コードは、Caché ターミナルで実行されます。これは、simplecallout.dll という名前のコー ルアウト・ライブラリをロードし、2 つの整数引数を加算して合計を返す AddInt と言う名前のライブラリ関数を呼 び出します。 USER> set sum = $ZF(-3,"simplecallout.dll","AddInt",2,2) USER> write "The sum is ",sum,! The sum is 4 この例では、$ZF(-3) を使用します。これは、単一のコールアウト・ライブラリ関数を呼び出す最も簡単な方法で す。その他のオプションは、“コールアウト・ライブラリ関数の呼び出し” を参照してください。 Caché コールアウト・ゲートウェイの使用法 11 Caché コールアウト・ライブラリの作成 simplecallout.dll コールアウト・ライブラリの複雑さは、それを呼び出すコードとあまり変わりません。すべてのコールアウ ト・ライブラリで必要とされる以下の 3 つの要素を含みます。 1. cdzf.h コールアウト・ヘッダ・ファイルを含めるときに提供される標準コード。 2. パラメータが正しく指定された 1 つ以上の関数。 3. ZFEntry テーブル のマクロ・コード。これは、ライブラリがロードされる際に Caché がコールアウト関数を見つけるた めに使用するメカニズムを生成します (詳細は、“ZFEntry テーブルの作成” を参照してください)。 simplecallout.dll コールアウト・ライブラリを生成するためにコンパイルされたコードは以下のとおりです。 simplecallout.dll のコールアウト・コード #include <cdzf.h> /* Required for all Callout code. */ #define ZF_DLL /* Required only for dynamically linked libraries. */ int AddTwoIntegers(int a, int b, int*outsum) { *outsum = a+b; /* set value to be returned by the $ZF function call */ return 0; /* set the exit status code */ } ZFBEGIN ZFENTRY("AddInt","iiP",AddTwoIntegers) ZFEND • 最初の行は、動的および静的リンク・コードの両方で必要な cdzf.h ファイルを含みます。 • 2 番目の行は、Caché にコードを静的にリンクする (“静的にリンクされたコールアウト関数” で後述) ので はなく、動的にリンクされたコールアウト・ライブラリを作成していることを示すスイッチである ZF_DLL を定 義します。 • AddTwoIntegers() 関数が次に定義されます。これには、以下の機能があります。 – 2 つの入力パラメータである整数 a と b、および 1 つの出力パラメータである整数ポインタ *outsum。 – 出力パラメータ *outsum に値を割り当てる文。これは、$ZF(-3) への呼び出しによって Caché に返さ れる値です。 – return 文は、関数出力値を返しません。代わりに、$ZF 呼び出しが正常に行われた場合に Caché によって受け取られる終了ステータス・コードを指定します。この関数が失敗した場合、Caché はシステ ムによって生成された終了ステータス・コードを受け取ります。 • 最後の 3 行は、Caché がコールアウト・ライブラリ関数を見つけるために使用する ZFEntry テーブルを生 成するマクロ呼び出しです。この例では、単一のエントリのみです。ここで、 – "AddInt" は、$ZF 呼び出し内の関数を識別するために使用される文字列です。 – "iiP" は、2 つの入力値および出力値のデータ型を指定する文字列です。 – AddTwoIntegers は、C 関数のエントリ・ポイント名です。 ZFEntry テーブルは、共有ライブラリをロードし、コールアウト・ゲートウェイによりアクセス可能にするメカニズムです (“ ZFEntry テーブルの作成” を参照)。ZFENTRY 宣言は、C 関数と ObjectScript $ZF 呼び出し間のインタフェースを 指定します。この例では、このインタフェースは、次のように動作します。 • C 関数宣言は、以下の 3 つのパラメータを指定します。 int AddTwoIntegers(int a, int b, int*outsum) パラメータ a および b は入力であり、outsum は、出力値を受け取ります。AddTwoIntegers の返り値は、終了ステー タス・コードであり、出力値ではありません。 • ZFENTRY マクロは、Caché 内での関数の識別方法およびパラメータが渡される方法を定義します。 12 Caché コールアウト・ゲートウェイの使用法 コールアウト・ライブラリの概要 ZFENTRY("AddInt","iiP",AddTwoIntegers) "AddInt" は、$ZF 呼び出し内の C 関数 AddTwoIntegers を指定するために使用されるライブラリ関数識別子で す。リンク宣言 ("iiP") は、パラメータ a および b をリンク・タイプ i (入力のみの整数) として、outsum をリンク・タ イプ P (入力および出力の両方に使用できる整数ポインタ) として宣言します。 • $ZF(-3) 関数呼び出しは、ライブラリ名、ライブラリ関数識別子、および入力パラメータを指定し、出力パラメータの 値を返します。 set sum = $ZF(-3,"simplecallout.dll","AddInt",2,2) パラメータ a および b は、最後の 2 つの引数によって指定されます。3 番目のパラメータ outsum は出力にのみ使 用されるため、引数は必要ありません。outsum の値は、$ZF(-3) 呼び出しが返されたときに sum に割り当てられま す。 3.1.1 ZFEntry テーブルの作成 すべてのコールアウト・ライブラリは、ZFEntry テーブルを定義する必要があり、これにより Caché がコールアウト関数を ロードしてアクセスできるようになります (簡単な例は “コールアウト・ライブラリの概要” を参照してください)。ZFEntry テーブルは ZFBEGIN で始まり ZFEND で終わるマクロ・コードのブロックによって生成されます。これら 2 つのマクロ間 で、関数を公開するごとに 1 回、ZFENTRY マクロを呼び出す必要があります。 各 ZFENTRY 呼び出しは、以下の 3 つの引数をとります。 zfentry(zfname,linkage,entrypoint) ここで、zfname は $ZF 呼び出し内で関数を指定するために使用される文字列、linkage は引数を渡す方法を指定する 文字列、entrypoint は C 関数のエントリ・ポイント名です。 既定では、ZFEntry テーブルは、静的にリンクされている関数にのみ使用できるコードを生成します (詳細は、“静的に リンクされたコールアウト関数” を参照してください)。コールアウト・ライブラリを作成するには、マクロ・コードがライブラリ 関数を見つけるための別のメカニズムを生成するようにするスイッチである #define ZF_DLL 指示文をコードに含める 必要があります。静的ポインタ・テーブルの代わりに、内部 GetZFTable 関数が生成されます。コールアウト・ライブラリが ロードされると、Caché はこの関数を呼び出して後続のライブラリ関数名の検索用にライブラリを初期化します。 注釈 ZFEntry のシーケンス番号 ZFEntry テーブル内のエントリの位置が重要となる場合があります。$ZF(-5) および $ZF(-6) インタフェース (次の章 “コールアウト・ライブラリ関数の呼び出し” で説明します) は、両方ともテーブル内でシーケンス番号 (1 で始まる) を指定することによってライブラリ関数を呼び出します。例えば、$ZF(-6) は以下の呼び出しを使 用して ZFEntry テーブル内の 3 番目の関数を呼び出します。 x = $ZF(-6,libID,3) ここで libID はライブラリ識別子、3 はテーブル内の 3 番目のエントリのシーケンス番号です。 注釈 OpenVMS のみ: ZFPRIV 文 OpenVMS システムでは、ZFENTRY マクロは ZFPRIV で置き換えることができます。これは、特権レベルを指 定する追加パラメータをとります (“特権レベルを上げる ZFPRIV の使用” を参照)。 Caché コールアウト・ゲートウェイの使用法 13 Caché コールアウト・ライブラリの作成 3.2 ZFEntry リンク・オプション 各 ZFENTRY 文 (“ZFEntry テーブルの作成” を参照) では、関数引数が渡される方法を決定する文字列が必要で す。このセクションでは、利用可能なリンク・オプションについて詳細に説明します。 • リンクの概要 — さまざまなリンク・タイプの概要を示し、この章で説明するすべてのリンク・オプションをリストします。 • 数値リンクの使用 — 数値パラメータのリンク・オプションを説明します。 • NULL で終了する文字列を C リンク・タイプで渡す — NULL で終了する文字列のリンク・オプションについて説明 します。 • 計算文字列を B リンク・タイプで渡す — 計算文字配列に ZARRAY 構造を使用するリンクについて説明します。 • Caché の長い文字列を J リンク・タイプで渡す — 計算文字配列に Caché CACHE_EXSTR 構造を使用するリンクに ついて説明します。 • $ZF ヒープの構成 — 文字列パラメータ渡しのメモリ割り当てを制御する Caché システム設定について説明します。 3.2.1 リンクの概要 各 ZFENTRY 文 (“ZFEntry テーブルの作成” を参照) では、引数が渡される方法を説明する文字列が必要です。例 えば、"iP" は、整数と整数へのポインタの 2 つのパラメータを指定します。2 番目の文字は、2 番目の引数が入力と出 力の両方に使用されることを指定するために大文字になっています。コードは、最大で 32 の実パラメータおよび仮パラ メータを持つことができます。 大文字のリンク・タイプを指定する場合 (i を除くすべてのリンク・タイプで許可されている)、入力と出力の両方にこの引 数を使用することができます。1 つの出力引数のみが指定されている場合は、その最終値は関数の返り値として使用さ れます。複数の出力引数が指定されている場合は、すべての出力引数がコンマ区切りの文字列として返されます。 出力引数は入力引数として使用する必要はありません。すべての入力引数の後に出力限定引数を指定する場合、関 数は出力引数のいずれも指定することなく呼び出すことができます (例は、“コールアウト・ライブラリの概要” を参照し てください)。 Caché ObjectScript プログラマの観点からすると、パラメータは入力のみです。実パラメータの値は $ZF 呼び出しによっ て評価され、C ルーチン宣伝内の仮パラメータにリンクされます。C 仮パラメータへの変更は失われるか、または$ZF 返 り値にコピー可能になるかのいずれかです。 ZFENTRY マクロが、仮パラメータを返り値として使用するように指定しない場合は、$ZF 呼び出しは空の文字列 ("") を 返します。リンク宣言は、1 つ以上の出力パラメータを含むことができます。この場合、すべての返り値は単一のコンマ区 切り文字列に変換されます。複数の返り値間に挿入されたコンマと、1 つの返り値内に存在するコンマとを区別する方法 はないため、最後の返り値のみがコンマを含むようにします。 以下のテーブルは、利用可能なオプションを説明しています。 C データ型 Input In/Out メモ int i なし (P を使用) i リンク・タイプは入力のみです。整数タイプを返すには、P (int *) を 使用します。入力引数は数値文字列の場合があります (メモ 1 参照)。 int * p P 入力引数は数値文字列の場合があります (メモ 1 参照)。 double * d D 入力引数は数値文字列の場合があります (メモ 1 参照)。#D を使用し て double * を基数 2 形式で保持します (メモ 2 を参照)。 14 Caché コールアウト・ゲートウェイの使用法 ZFEntry リンク・オプション C データ型 Input In/Out メモ float * f F 入力引数は数値文字列の場合があります (メモ 1 参照)。#F を使用し て float * を基数 2 形式で保持します (メモ 2 を参照)。 char * 1c また はc 1C また はC これは、一般的な C NULL 終了文字列です (メモ 3 を参照)。 unsigned short * 2c また はw 2C また はW これは、C 形式の NULL 終了 UTF-16 文字列です (メモ 3 を参照)。 wchar t * 4c 4C これは、wchar_t 要素のベクトルとして保存される C 形式の NULL 終 了文字列です (メモ 3 および 4 を参照)。 ZARRAYP 1b また はb 1B また はB 最大 32,767 文字の 8 ビット各国語文字列。 ZWARRAYP 2b また はs 2B また はS 最大 32,767 文字の 16 ビット Unicode 文字列。 ZHARRAYP 4b 4B wchar_t によって実装される要素内に保存される、最大 32,767 文字 の Unicode 文字列 (メモ 4 参照)。 CACHE_EXSTR 1j また はj 1J また はJ 8 ビット各国語文字の Caché の長い文字列。 CACHE_EXSTR 2j また はn 2J また はN 16 ビット Unicode 文字の Caché の長い文字列。 CACHE_EXSTR 4j 4J wchar_t 文字の Caché の長い文字列 (メモ 4 参照)。 1. i、p、d、f — 数値引数が指定されると、Caché では文字列の入力引数が許可されます。詳細は、“数値リンクの使 用” を参照してください。 2. #F、#D — 数値を基数 2 浮動小数点形式で保持するには、float * で #F を使用するかまたは double * で #D を使 用します。詳細は、“数値リンクの使用” を参照してください。 3. 1C、2C、4C — このリンクで渡されるすべての文字列は最初の NULL 文字で切り捨てられます。詳細は、“NULL で 終了する文字列を C リンク・タイプで渡す” を参照してください。 4. 4B、4C、4J — wchar_t が一般的に 32 ビットであっても、Caché では 16 ビットのみを使用して各 Unicode 文字を格 納するため、これらのリンクは wchar_t の使用を指定する既存のコードまたはシステム・インタフェースとやり取りする ときにのみ役立ちます。 構造体と引数のプロトタイプ定義 (インターシステムズ内部定義を含む) は、インクルード・ファイル cdzf.h にあります。 注釈 OpenVMS 用の V リンク この章で説明しているリンク・タイプに加えて、OpenVMS システム・サービスを呼び出す際には V リンクを使用 することができます (“システム・サービスでの V リンクの使用” を参照)。 3.2.2 数値リンクの使用 数値リンク・タイプは、以下のデータ型用に提供されています。 Caché コールアウト・ゲートウェイの使用法 15 Caché コールアウト・ライブラリの作成 C データ型 Input In/Out メモ int i なし (P を使 用) i リンク・タイプは入力のみです。整数タイプを返すには、代わりに P を使用します。 int * p P int へのポインタです。 double * d D #D (出力のみ) を使用して double * を基数 2 形式で返します。 float * f F #F (出力のみ) を使用して float * を基数 2 形式で返します。 数値引数が指定されると、Caché では文字列の入力引数が許可されます。文字列が渡されると、先頭の数字が文字列 から解析されて数値が派生します。先頭の数字がない場合は、値 0 が受け取られます。つまり、"2DOGS" は 2.0 とし て受け取られますが、"DOG" は 0.0 として受け取られます。整数の引数は切り捨てられます。例えば、"2.1DOGS" は 2 として受け取られます。詳細は、"Caché ObjectScript の使用法" の “文字列から数値への変換” を参照してくださ い。 注釈 浮動小数点数での精度の保持 出力リンクが F (float *) または D (double *) で指定されている場合、返す数値は Caché の内部基数 10 の数 の形式に変換されます。数値を基数 2 形式で保持するには、float * で #F を使用するかまたは double * で #D を使用します。 入力引数では # 接頭語は許可されていません。変換を回避するには、関数を呼び出す ObjectScript コード 内で $DOUBLE を使用して入力値を作成する必要があり、対応する入力リンクは小文字の f または d として 指定される必要があります。 既定では、Caché は、10 進法で小数を格納します。例えば、数値 1.3 は 13*.10 として格納されます。一方、大半の 高レベル言語は、2 進数の形式で小数を格納します (2 進数と 2 の累乗の積)。引数を f (float *) または d (double *) として記述する場合、Caché は、入力時に 10 進数値を 2 進数値に変換し、出力時に 10 進数値に戻します。この変換 により、値に若干の誤差が生じる可能性があります。 Caché は標準の IEEE 形式の 64 ビット浮動小数点を作成する $DOUBLE 関数をサポートします。これらの数は、精度 を失うことなく外部関数と Caché 間で渡すことができます (外部関数が 64 ビットの double ではなく 32 ビットの float を 使用する場合を除く)。出力では、IEEE 形式の使用は、接頭語 # を F または D の引数タイプへ追加すると、指定でき ます。例えば、"i#D" は整数の入力引数 1 つと、64 ビット浮動小数点出力引数 1 つに引数リストを指定します。 3.2.3 NULL で終了する文字列を C リンク・タイプで渡す このリンク・タイプは、Caché が NULL ($CHAR(0)) 文字を含む文字列を送信しないことがわかっている場合にのみ使用 します。このデータ型を使用する際は、C 関数は、Caché 文字列が長い場合でも、Caché によって渡される文字列を最 初の NULL 文字で切り捨てます。例えば、Caché 文字列 "ABC"_$CHAR(0)_"DEF" は、"ABC" に切り捨てられます。 C データ型 Input In/Out メモ char * 1c または c 1C または C これは、一般的な C NULL 終了文字列です。 unsigned short * 2c または w 2C または W これは、C 形式の NULL 終了 UTF-16 文字列です。 wchar t * 4c 4C これは、wchar_t 要素のベクトルとして保存される C 形式の NULL 終了文字列です。 数値文字列を返すために 3 つすべてのリンク・タイプを使用する短いコールアウト・ライブラリを以下に示します。 16 Caché コールアウト・ゲートウェイの使用法 ZFEntry リンク・オプション C リンクを使用した NULL 終了文字列渡し 以下の 3 つの関数それぞれは、ランダム整数を生成して最大 6 桁の数値文字列に変換し、C リンクを使用し てその文字列を返します。 #define ZF_DLL // Required when creating a Callout library. #include <cdzf.h> #include <stdio.h> #include <wchar.h> // Required for 2-byte and 4-byte strings int get_sample(char* retval) { // 1-byte, null-terminated sprintf(retval,"%d",(rand()%1000000)); return ZF_SUCCESS; } int get_sample_W(unsigned short* retval) { // 2-byte, null-terminated swprintf(retval,6,L"%d",(rand()%1000000)); return ZF_SUCCESS; } int get_sample_H(wchar_t* retval) { // 4-byte, null-terminated swprintf(retval,6,L"%d",(rand()%1000000)); return ZF_SUCCESS; } ZFBEGIN ZFENTRY("GetSample","1C",get_sample) ZFENTRY("GetSampleW","2C",get_sample_W) ZFENTRY("GetSampleH","4C",get_sample_H) ZFEND 3.2.4 計算文字列を B リンク・タイプで渡す cdzf.h コールアウト・ヘッダ・ファイルは、計算文字列構造 ZARRAY、ZWARRAY、および ZHARRAY を定義します。これ らの構造は、文字要素の配列 (それぞれ、8 ビット、16 ビット Unicode、または wchar t) および配列内の要素の数を指 定する整数を含みます。以下はその例です。 typedef struct zarray { unsigned short len; unsigned char data[1]; /* 1 is a dummy value */ } *ZARRAYP; 以下はその説明です。 • len — 配列の長さが格納されます。 • data — 文字データを格納する配列です。要素タイプは、ZARRAY は unsigned char、ZWARRAY は unsigned short、 ZHARRAY は wchar_t です。 B リンクは、3 つの配列構造に対応して、ポインタ型 ZARRAYP、ZWARRAYP、および ZHARRAYP を指定します。 C データ型 Input In/Out メモ ZARRAYP 1b または b 1B または B 8 ビットの最大 32,767 文字を含む各国語文字列。 ZWARRAYP 2b または s 2B または S 16 ビットの最大 32,767 文字を含む Unicode 文字列。 ZHARRAYP 4b 4B 最大 32,767 の wchar_t 文字を含む Unicode 文字列。 返された最大配列サイズは、最大文字列サイズの 32,767 文字です。引数の最大合計長さは、1 文字あたりのバイト数 に依存します (“$ZF ヒープの構成” を参照)。 数値文字列を返すために 3 つすべてのリンク・タイプを使用する短いコールアウト・ライブラリを以下に示します。 Caché コールアウト・ゲートウェイの使用法 17 Caché コールアウト・ライブラリの作成 B リンクを使用した計算文字列渡し 以下の 3 つの関数それぞれは、ランダム整数を生成して最大 6 桁の数値文字列に変換し、B リンクを使用し て文字列を返します。 #define ZF_DLL // Required when creating a Callout library. #include <cdzf.h> #include <stdio.h> #include <wchar.h> // Required for 2-byte and 4-byte strings int get_sample_Z(ZARRAYP retval) { // 1-byte, counted unsigned char numstr[6]; sprintf(numstr,"%d",(rand()%1000000)); retval->len = strlen(numstr); memcpy(retval->data,numstr,retval->len); return ZF_SUCCESS; } int get_sample_ZW(ZWARRAYP retval) { // 2-byte, counted unsigned short numstr[6]; swprintf(numstr,6,L"%d",(rand()%1000000)); retval->len = wcslen(numstr); memcpy(retval->data,numstr,(retval->len*sizeof(unsigned short))); return ZF_SUCCESS; } int get_sample_ZH(ZHARRAYP retval) { // 4-byte, counted wchar_t numstr[6]; swprintf(numstr,6,L"%d",(rand()%1000000)); retval->len = wcslen(numstr); memcpy(retval->data,numstr,(retval->len*sizeof(wchar_t))); return ZF_SUCCESS; } ZFBEGIN ZFENTRY("GetSampleZ","1B",get_sample_Z) ZFENTRY("GetSampleZW","2B",get_sample_ZW) ZFENTRY("GetSampleZH","4B",get_sample_ZH) ZFEND 注釈 複数の値を含む出力引数文字列ではコンマが区切り文字として使用されます。コンマは計算文字列配列の一 部となるため、引数リストの最後にこれらの配列を宣言し、呼び出しごとに 1 つの配列を使用します。 3.2.5 Caché の長い文字列を J リンク・タイプで渡す J リンクは、Caché の長い文字列を渡す方法を提供します。"Caché プログラミング入門ガイド" の “長い文字列演算の サポート” および “長い文字列の制限” を参照してください。長い文字列が既定で有効になります。 C データ型 Input In/Out メモ CACHE_EXSTR 1j また はj 1J また はJ 8 ビット各国語文字の Caché の長い文字列。 CACHE_EXSTR 2j また はn 2J また はN 16 ビット Unicode 文字の Caché の長い文字列。 CACHE_EXSTR 4j 4J wchar_t 文字の Caché の長い文字列。 callin.h ヘッダ・ファイル ("Caché コールイン API の使用法" の “callin.h ヘッダ・ファイル” を参照) は、計算文字列構 造 CACHE_EXSTR を定義します。この構造は、文字要素の配列 (8 ビット、16 ビット Unicode、または wchar t) および 配列内の要素の数を指定する整数を含みます。 18 Caché コールアウト・ゲートウェイの使用法 ZFEntry リンク・オプション typedef struct { unsigned int len; union { Callin_char_t *ch; unsigned short *wch; wchar_t *lch; /* OR unsigned short *lch if } str; } CACHE_EXSTR, *CACHE_EXSTRP; /* length of string */ /* text of the 8-bit string */ /* text of the 2-byte string */ /* text of the 4-byte string */ 4-byte characters are not enabled */ 次の 2 つの Caché コールイン関数 ("Caché コールイン API の使用法" の “コールイン関数リファレンス” を参照) は、 CACHE_EXSTR の作成または削除に使用されます。 • CacheExStrKill — CACHE_EXSTR 文字列に関連付けられているストレージを解放します。 • CacheExStrNew[W][H] — 文字列に対して要求されたストレージの容量を割り当て、CACHE_EXSTR 構造に、構造 の長さおよび構造の値フィールドへのポインタを埋め込みます。 これらの関数の使用方法のデモンストレーションは、以下の例を参照してください。 数値文字列を返すために 3 つすべてのリンク・タイプを使用する短いコールアウト・ライブラリを以下に示します。 J リンク を使用した Caché の長い文字列渡し 以下の 3 つの関数それぞれは、ランダム整数を生成して最大 6 桁の数値文字列に変換し、J リンクを使用して 文字列を返します。 #define ZF_DLL // Required when creating a Callout library. #include <cdzf.h> #include <stdio.h> #include <wchar.h> // Required for 2-byte and 4-byte strings #include <callin.h> // Required for Caché long strings int get_sample_L(CACHE_EXSTRP retval) { // 1-byte, longstring Callin_char_t numstr[6]; size_t len = 0; sprintf(numstr,"%d",(rand()%1000000)); len = strlen(numstr); CACHEEXSTRKILL(retval); if (!CACHEEXSTRNEW(retval,len)) {return ZF_FAILURE;} memcpy(retval->str.ch,numstr,len); // copy to retval->str.ch return ZF_SUCCESS; } int get_sample_LW(CACHE_EXSTRP retval) { // 2-byte, longstring unsigned short numstr[6]; size_t len = 0; swprintf(numstr,6,L"%d",(rand()%1000000)); len = wcslen(numstr); CACHEEXSTRKILL(retval); if (!CACHEEXSTRNEW(retval,len)) {return ZF_FAILURE;} memcpy(retval->str.wch,numstr,(len*sizeof(unsigned short))); return ZF_SUCCESS; } // copy to retval->str.wch int get_sample_LH(CACHE_EXSTRP retval) { // 4-byte, longstring wchar_t numstr[6]; size_t len = 0; swprintf(numstr,6,L"%d",(rand()%1000000)); len = wcslen(numstr); CACHEEXSTRKILL(retval); if (!CACHEEXSTRNEW(retval,len)) {return ZF_FAILURE;} memcpy(retval->str.lch,numstr,(len*sizeof(wchar_t))); // copy to retval->str.lch return ZF_SUCCESS; } ZFBEGIN ZFENTRY("GetSampleL","1J",get_sample_L) ZFENTRY("GetSampleLW","2J",get_sample_LW) ZFENTRY("GetSampleLH","4J",get_sample_LH) ZFEND Caché コールアウト・ゲートウェイの使用法 19 Caché コールアウト・ライブラリの作成 注釈 CACHE_EXSTRP 入力引数の常時削除 前述の例では、CACHEEXSTRKILL(retval) は、メモリから入力引数を削除するために常に呼び出されてい ます。これは、引数が出力に使用されない場合でも常に実行する必要があります。実行しない場合は、メモリ・ リークが発生します。 3.2.6 $ZF ヒープの構成 $ZF ヒープは、すべての $ZF 入力および出力パラメータに割り当てられる仮想メモリ領域です。これは、以下の Caché システム設定によって制御されます。 • ZFString は、1 つの文字列パラメータに対して使用が許可される文字数です。このために実際に必要なバイト数は、 使用している文字が 8 ビット文字か、2 バイトの Unicode 文字か、UNIX® 上の 4 バイト文字かによって異なります。 この設定で許可されている範囲は、0 から 32767 文字です。既定は、0 であり、最大値を使用することを示します。 • ZFSize は、Caché がすべての $ZF 入力および出力パラメータに割り当てる合計バイト数です。この設定で許可され ている範囲は、0 から 270336 バイトです。0 (既定の設定) は、Caché が ZFString の値に基づいて適切な値を計 算することを示します。 以下のように ZFSize (合計バイト数) を ZFString (文字列あたりの最大文字数) に基づいて計算します。 ZFSize = (<bytes per character> * ZFString) + 2050 例えば、ZFString の値が既定の 32767 文字だとします。 • Unicode 2 バイト文字を使用すると、ZFSize の適切な値は (2 * 32767 + 2050) = 67584 バイトになります。 • UNIX® 4 バイト文字を使用すると、ZFSize の適切な値は (4 * 32767 + 2050) = 133118 バイトになります。 これらの設定は、以下のいずれかの場所で変更できます。 • Caché パラメータ・ファイル ("Caché パラメータ・ファイル・リファレンス" の “[config]” セクションの “zfheap” を参 照してください)。 • 管理ポータル ("Caché 追加構成設定リファレンス" の “詳細メモリ設定” にある ZFSize および ZFString のエント リを参照してください)。 3.3 コールアウト・ライブラリの Runup 関数と Rundown 関数 Caché コールアウト・ライブラリは、共有オブジェクトがロードされたとき (runup) またはアンロードされたとき (rundown) に 呼び出されるカスタム内部関数を含むことができます。どちらのケースも引数は渡されません。関数は以下のように使用 されます。 • ZFInit — コールアウト・ライブラリが $ZF(-3)、$ZF(-4,1)、または $ZF(-6) によって最初にロードされたときに呼び出 されます。この関数からの返りコードは、エラーがないことを示すゼロ、もしくはいくつかの障害の存在を示すゼロ以 外の値になります。呼び出しが正常に実行されると、ZFUnload rundown 関数のアドレスが保存されます。 • ZFUnload — コールアウト・ライブラリが $ZF(-3) への呼び出しによってアンロードまたは置換されたとき、あるいは $ZF(-4,2) または $ZF(-4,4) によってアンロードされたときに呼び出されます。プロセスの停止では呼び出されませ ん。エラーが rundown 関数実行中に発生した場合、それ以降、コールアウト・ライブラリのアンロードを許可するた めの呼び出しは無効となります。ZFUnload からの返り値は現在無視されています。 コールアウト・ライブラリを構築する際、リンクを確立するプロシージャの間に、ZFInit と ZFUnload 記号を明示的にエクス ポートする必要がある場合があります。 20 Caché コールアウト・ゲートウェイの使用法 トラブルシューティング 3.4 トラブルシューティング ほとんどすべてのルーチンをコールアウト・ゲートウェイで呼び出すことができますが、そうしなければならないという意味 ではありません。これは、数学関数で使用するのが最適であり、Caché I/O でうまく処理されない外部デバイスへのイン タフェース、または Caché インタフェースが存在しないシステム・サービスの場合に効果的に使用することができます。 以下の動作によって重大な問題が発生する可能性があります。 • 自身に属していないメモリへのアクセス メモリ・アクセス違反は、Caché によって処理され、Caché 内のバグとして扱われます。 • トラップによって処理されるその他のエラーの発生 トラップによって処理されるエラー (ほとんどのプラットフォーム上でのゼロによる除算など) も Caché 内のバグとして 扱われます。 • プロセスの優先度の変更 Caché は、Caché を実行している他のプロセスと相互作用する必要があります。優先度を下げると、上げるのと同様 に問題が発生する場合があります。例えば、プロセスが CPU を解放する直前にスピン・ロックで保護されたリソース を取得することを考えてみましょう。優先度が低すぎると、高い優先度のその他のプロセスがリソースを奪い合い、事 実上、スピン・ロックを解除できるようにするプロセスの実行を妨げます。 • 中断のマスク インターロックを実装するために中断を短時間マスクする場合がありますが、中断をマスクしたままにしないように十 分注意する必要があります。 • 削除できないリソースを作成または開く ファイルを開いて malloc を使用してメモリを割り当てることは問題ありません。それらのリソースはプロセスの終了時 に閉じられるかまたは解放されます。2 番目のスレッドを作成すると、2 番目のスレッドが Caché プロセスの終了前 に正常に終了することを保証できないため、2 番目のスレッドは作成しないでください。 • opaque 以外のオブジェクトを ObjectScript 以外のコードで返す コード内のメモリのブロックを malloc して、それを読み取るために $VIEW(address,−3,size) を使用できると考 えないでください。また、ObjectScript 以外のコードに malloc ブロックを戻さないでください。コードは opaque ハン ドルを返し、後で opaque ハンドルを受け取った時に使用する前に有効であることを確認する必要があります。 • プロセスの終了 exit だけを呼び出すことはしないでください。常に ZF_SUCCESS または ZF_FAILURE のいずれかと共に返しま す (これらの値の実装は Caché プラットフォーム間で異なることに留意してください)。 • exec のいずれかのバージョンの呼び出しによる終了 子プロセス内で fork してから exec を呼び出すことはできますが、必ず親は Caché に返り、子プロセスは Caché に 返らないようにしてください。これは、OpenVMS で LIB$DO_COMMAND を使用する際にも当てはまります。 • プロセスでのエラー処理の振る舞いの変更 OpenVMS および Windows のみが、現在の内部フレームのローカル・エラー処理を確立することを許可するため、 この点においては、これらのシステムは UNIX® システムよりも有利です。 Caché コールアウト・ゲートウェイの使用法 21 4 コールアウト・ライブラリ関数の呼び出し コールアウト・ゲートウェイは、実行時に Caché コールアウト・ライブラリをロードし、そのライブラリから関数を呼び出すた めに使用できる 3 つの異なるインタフェースを提供します。この章では、以下の項目について説明します。 • コールアウト・ライブラリのインタフェース — 3 つのコールアウト・ライブラリのインタフェースの概要とその使用方法を 説明します。 • 単純なライブラリ関数呼び出しでの $ZF(-3) の使用 — 一度に 1 つのライブラリをロードして使用する便利な方法を 提供する $ZF(-3) について説明します。 • システム ID によるライブラリへのアクセスでの $ZF(-5) の使用 — ライブラリをロードして使用するより効率的な方法 を提供する $ZF(-5) および関連する関数について説明します。 • ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 — ハードコード化されたライブラリ・ファイル 名を指定するのではなくユーザ作成のインデックス・テーブルを読み取ることによってライブラリをロードする点を除 いて $ZF(-5) と類似のインタフェースを提供する $ZF(-6) および関連する関数について説明します。 注釈 共有ライブラリとコールアウト・ライブラリ このドキュメントでは、共有ライブラリという用語は、動的にリンクされたファイル (Windows の DLL ファイル、 UNIX® および関連オペレーティング・システムの SO ファイル、または OpenVMS の共有可能イメージ・ファイ ル) を示します。コールアウト・ライブラリは、コールアウト・ゲートウェイへのフックを含む共有ライブラリであり、 多様な $ZF 関数が実行時にロードして、その関数を呼び出すことができるようにします。コールアウト・ライブラ リを記述する手順については、“Caché コールアウト・ライブラリの作成” を参照してください。 4.1 コールアウト・ライブラリのインタフェース $ZF(-3)、$ZF(-5)、および $ZF(-6) 関数はすべて、コールアウト・ライブラリ関数を呼び出すために使用されますが、これ らの関数のそれぞれが、独自の強さと弱さを持っています。 $ZF(-3) インタフェース $ZF(-3) 関数はコールアウト・ライブラリをロードして、ライブラリ・ファイル・パスと関数名を指定することによって ライブラリ関数を呼び出します。使用は簡単ですが、仮想メモリ内で使用できるのは一度に 1 つのライブラリの みです。その他のインタフェースとは異なり、ライブラリ関数を呼び出す前に初期化を行う必要がありません。詳 細は、“単純なライブラリ関数呼び出しでの $ZF(-3) の使用” を参照してください。 Caché コールアウト・ゲートウェイの使用法 23 コールアウト・ライブラリ関数の呼び出し $ZF(-5) インタフェース $ZF(-5) 関数は、コールアウト・ライブラリおよびライブラリ関数にシステム定義の数値識別子を指定することに よってコールアウト・ライブラリ関数を呼び出します。これは同時にいくつかのライブラリをメモリ内に保持するこ とができ、個々の関数呼び出しは $ZF(-3) よりも効率的です。$ZF(-5) インタフェースもユーティリティ関数 $ZF(-4,1)、$ZF(-4,2)、および $ZF(-4,3) を含みます。これは、ライブラリおよび関数 ID を取得するため、およ びライブラリをロードまたはアンロードするために使用する必要があります。詳細は、“システム ID によるライブ ラリへのアクセスでの $ZF(-5) の使用” を参照してください。 $ZF(-6) インタフェース $ZF(-6) インタフェースは、コールアウト・アプリケーションが実際のライブラリ・ファイル名をハードコード化する ことなくライブラリをロードできる点を除いて $ZF(-5) と類似しています。代わりに、別のインデックス・テーブル がその情報を含み、各インデックス・ライブラリに一意のユーザ定義インデックス番号が指定されます。インデッ クス・テーブルが Caché のインスタンス内で定義されると、そのインスタンス内のすべてのコールアウト・アプリ ケーションで利用可能になります。$ZF(-6) 関数は、インデックス番号および関数 ID を指定することによってラ イブラリ関数を呼び出します。必要に応じて、自動的にインデックス・テーブルを読み取って指定されたライブラ リをロードします。$ZF(-6) インタフェースもユーティリティ関数 $ZF(-4,4) ~ $ZF(-4,8) を含みます。これは、ラ イブラリをアンロードするため、およびインデックスを作成または維持するために使用する必要があります。詳細 は、“ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” を参照してください。 4.2 単純なライブラリ関数呼び出しでの $ZF(-3) の使用 $ZF(-3) 関数は、コールアウト・ライブラリをロードして、そのライブラリから指定した関数を実行するために使用されます。 $ZF(-3) は、1 つのライブラリのみを使用している場合、またはライブラリのロードのオーバーヘッドを懸念して十分な呼 び出しを行っていない場合に、もっとも役立ちます。これにより、ライブラリ名、関数名、および関数引数のコンマ区切り のリストを指定することによって、任意の利用可能なライブラリ関数を呼び出すことができます。 result = $ZF(-3, library_name[, function_name[, arguments]]) 指定されたライブラリは、$ZF(-3) への前の呼び出しによってロードされていない場合にロードされます。一度にロードで きるのは 1 つのライブラリのみです。後続の $ZF(-3) 呼び出しが、別のライブラリを指定すると、古いライブラリはアンロー ドされ、新しいライブラリが置き換わります。このライブラリは、後続の $ZF(-3) 呼び出しが同じライブラリを指定する限り ロードされたままになります。ライブラリがロードされた後に、後続の呼び出しで、ライブラリ名を NULL 文字列 ("") として 指定できます。 関数を呼び出すことなくライブラリをロードまたはアンロードすることができます。新しいライブラリをロードするには、ライ ブラリ名のみを指定します。新しいライブラリをロードせずに現在のライブラリをアンロードするには、NULL 文字列のみ を指定します。いずれのケースでも、$ZF(-3) は、ロードまたはアンロードが成功したかどうかを示すステータス・コードを 返します。 以下の ObjectScript コードは、2 つの異なるライブラリそれぞれから 2 つの異なる関数を呼び出し、現在のライブラリを アンロードします。 24 Caché コールアウト・ゲートウェイの使用法 システム ID によるライブラリへのアクセスでの $ZF(-5) の使用 ライブラリのロードおよび関数の呼び出しでの $ZF(-3) の使用 // define Callout library paths set libOne = "c:\intersystems\cache\bin\myfirstlibrary.dll" set libTwo = "c:\intersystems\cache\bin\anotherlibrary.dll" //load and call SET result1=$ZF(-3,libOne,"FuncA",123) // loads libOne and calls FuncA SET result2=$ZF(-3,"","FuncB","xyz") // calls FuncB from same library //load, then call with null name SET status=$ZF(-3,libTwo) // unloads libOne, loads libTwo SET result1=$ZF(-3,"","FunctionOne","arg1") SET result2=$ZF(-3,"","FunctionTwo","argA", "argB") //unload SET status=$ZF(-3,"") // unloads libTwo • 簡便性のため、ライブラリ名は文字列 libOne および libTwo に割り当てられます。 • $ZF(-3) への最初の呼び出しは、コールアウト・ライブラリ libOne をロードし、そのライブラリから関数 FuncA を呼び出します。 • 2 番目の呼び出しは、ライブラリ名に NULL 文字列を指定して、現在ロードされている libOne を再び使用 することを示し、そのライブラリから関数 FuncB を呼び出します。 • $ZF(-3) への 3 番目の呼び出しは、ライブラリ名 libTwo のみを指定します。これにより、libOne がアンロー ドされ、libTwo がロードされますが、ライブラリ関数は呼び出されません。この呼び出しは libTwo が正常に ロードされたかどうかを示すステータス・コードを返します。 • 4 番目と 5 番目の呼び出しは、ライブラリ関数 FunctionOne および FunctionTwo を現在ロードされている libTwo から呼び出します。 • 最後の $ZF(-3) 呼び出しは、ライブラリ関数を呼び出さず、ライブラリ名に NULL 文字列を指定します。こ れにより、libTwo がアンロードされ、新しいライブラリはロードされません。この呼び出しは libTwo が正常に アンロードされたかどうかを示すステータス・コードを返します。 この章の以下のセクションでは、一度に複数のライブラリをロードできる $ZF 関数について説明します。これらの関数は $ZF(-3) と競合しません。$ZF(-3) は、いつでもそれ自体のライブラリのプライベート・コピーをロードおよびアンロードし ているかのように使用することができます。 4.3 システム ID によるライブラリへのアクセスでの $ZF(-5) の使 用 $ZF(-5) 関数は、ライブラリ関数の呼び出しにシステム定義のライブラリおよび関数の識別子を使用します。ユーティリ ティ関数 $ZF(-4,1)、$ZF(-4,2) および $ZF(-4,3) は、必要な識別子を取得し、ライブラリをロードまたはアンロードする ために使用されます。複数のライブラリを同時に開くことができます。$ZF(-3) とは異なり (“単純なライブラリ関数呼び出 しでの $ZF(-3) の使用” を参照)、$ZF(-5) は、ライブラリをロードして識別子を取得するためにユーティリティ関数が呼 び出されるまで使用できません。ただし、各ライブラリは、一度のみロードが必要であり、各ライブラリまたは関数識別子 は一度のみ生成する必要があります。多くのライブラリ関数呼び出しを行うアプリケーションでは、これにより処理のオー バーヘッドが大幅に削減できます。 このセクションでは、以下の $ZF 関数について説明しています。 • $ZF(-5) — システム定義のライブラリおよび関数の識別子によって参照されるコールアウト・ライブラリ関数を呼び出 します。 • $ZF(-4,1) — ファイル名によって指定されるコールアウト・ライブラリをロードし、それに対するシステム定義の ID 値 を返します。 Caché コールアウト・ゲートウェイの使用法 25 コールアウト・ライブラリ関数の呼び出し • $ZF(-4,2) — ライブラリ ID によって指定されるコールアウト・ライブラリをアンロードします。 • $ZF(-4,3) — 指定されたライブラリ ID および関数名の関数 ID 値を返します。 $ZF(-4,1) および $ZF(-4,3) 関数は、コールアウト・ライブラリのロードとライブラリおよび関数識別子の取得に使用され ます。$ZF(-4,1) の構文は以下のとおりです。 lib_id = $ZF(-4,1,lib_name) // get library ID ここで lib_name は、共有ライブラリ・ファイルのフルネームとパスであり、lib_id は、返されるライブラリ ID です。$ZF(-4,3) の構文は以下のとおりです。 func_id=$ZF(-4,3,lib_id, func_name) // get function ID ここで lib_id は、ライブラリ ID、func_name は、ライブラリ関数名、func_id は、返される関数 ID 値です。 以下の ObjectScript コードはコールアウト・ライブラリ mylibrary.dll をロードしてライブラリ ID を取得し、"MyFunction" の関数 ID を取得して $ZF(-5) を使用して呼び出します。 $ZF(-5) を使用したライブラリのロードと関数の呼び出し set libID = $ZF(-4,1,"C:\calloutlibs\mylibrary.dll") set funcID = $ZF(-4,3,libID, "MyFunction") set x = $ZF(-5,libID, funcID, "arg1") 識別子が定義されると、ライブラリは $ZF(-4,2) によってアンロードされるまでロードされたままになり、その識別子は $ZF(-4,1) または $ZF(-4,3) へのさらなる呼び出しを行うことなく使用することができます。これにより、複数のライブラリ からの関数が何度も呼び出される際の処理オーバーヘッドが大幅に削減されます。 以下の ObjectScript コードは 2 つの異なるライブラリをロードし、ロング・ループで両方のライブラリから関数を呼び出し ます。inputlibrary.dll 内の関数は、データ・サンプルを取得し、outputlibrary.dll 内の関数は、データをプロットおよび保 存します。 複数ライブラリおよび多くの関数の呼び出しでの $ZF(-5) の使用 Method GraphSomeData(loopsize As %Integer=100000) As %Status { // load libraries and get system-defined ID values set InputLibID = $ZF(-4,1,"c:\intersystems\cache\bin\inputlibrary.dll") set OutputLibID = $ZF(-4,1,"c:\intersystems\cache\bin\outputlibrary.dll") set fnGetSample = $ZF(-4,3,InputLibID,"GetSample") set fnAnalyzeData = $ZF(-4,3,OutputLibID,"AnalyzeData") set fnPlotPoint = $ZF(-4,3,OutputLibID,"PlotPoint") set fnWriteData = $ZF(-4,3,OutputLibID,"WriteData") // call functions from each library until we have 100000 good samples do { set sample = $ZF(-5,InputLibID,fnGetSample) set normalized = $ZF(-5,OutputLibID,fnAnalyzeData,sample) if (normalized>"") { set flatdata($INCREMENT(count)) = normalized } } while (count<loopsize) set status = $ZF(-4,2,InputLibID) //unload "inputlibrary.dll" // plot results of the previous loop and write to output for point=1:1:loopsize { set list = $ZF(-5,OutputLibID,fnPlotPoint,flatdata(point)) set x = $PIECE(list,",",1) set y = $PIECE(list,",",2) set sc = $ZF(-5,OutputLibID,fnWriteData,flatdata(point),x,y,"outputfile.dat") } set status = $ZF(-4,2,OutputLibID) //unload "outputlibrary.dll" quit 0 } • $ZF(-4,1) への呼び出しでは、コールアウト・ライブラリ inputlibrary.dll および outputlibrary.dll を仮想メモ リ内にロードし、それらのシステム定義のライブラリ ID を返します。 26 Caché コールアウト・ゲートウェイの使用法 ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 • $ZF(-4,3) への呼び出しでは、ライブラリ ID および関数名を使用してライブラリ関数の ID を取得します。 返された関数 ID は実際は ZFEntry テーブル・シーケンス番号 (前の章の “ZFEntry テーブルの作成” を参照) です。 • 最初のループでは、$ZF(-5) を使用して各ライブラリから関数を呼び出します。 – inputlibrary.dll からの GetSample() 関数は、未指定のソースから生のデータを読み取ります。 – outputlibrary.dll からの AnalyzeData() 関数は、生のデータを正規化するかまたは拒否して、空の文字 列を返します。 – 正規化された各サンプルは、flatdata(count) (ここで Caché 関数 $INCREMENT への最初の呼び出し が count を作成し、1 に初期化する) に保存されます。 既定では、ループは 100000 のサンプルを取得します。両方のライブラリがロードされメモリ内に残ってい るため、2 つの異なるライブラリ間を切り替えるための処理オーバーヘッドはありません。 • 最初のループが終了した後に、ライブラリ inputlibrary.dll は必要なくなるため、$ZF(-4,2) が呼び出されて アンロードされます。ライブラリ outputlibrary.dll は、メモリ内に残ります。 • 2 番目のループは、配列 flatdata からの各サンプルを処理し、未指定の場所にあるファイルに書き込みま す。 • – ライブラリ関数 PlotPoint() は、サンプルを読み取り、プロットされる座標を含むコンマ区切り文字列を 返します (ライブラリ関数から複数の出力パラメータが返される方法の説明は、“リンクの概要” を参照 してください)。 – Caché $PIECE 関数は、座標値 x および y を文字列から抽出するために使用されます。 – ライブラリ関数 WriteData() は、サンプルおよび座標を outputfile.dat ファイルに保存します。これは、 グラフを出力するために他のアプリケーションで使用されます。 2 番目のループが終了した後に、$ZF(-4,2) が再び呼び出されてライブラリ outputlibrary.dll がアンロード されます。 以下のセクションでは、$ZF(-6) インタフェースについて説明します。これは、$ZF(-5) インタフェースと同じ仮想メモリ領 域内にライブラリをロードします。 4.4 ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 $ZF(-6) 関数は、グローバルに定義されたインデックスを介してコールアウト・ライブラリへのアクセスを可能にする、共有 ライブラリ・ファイルの場所を認識していないアプリケーションでも使用可能な効率的なインタフェースを提供します。ユー ザ定義のインデックス・テーブルは、ライブラリ ID 番号と対応するライブラリ・ファイル名で構成されるキーと値のペアを 格納します。指定されたライブラリ ID と関連付けられているファイル名は、ライブラリ・ファイルの名前が変更されたときま たは再配置されたときに変更できます。この変更は、インデックス番号でライブラリをロードするアプリケーションに対して 透過的です。その他の $ZF 関数は、インデックス・テーブルを作成して維持するため、および $ZF(-6) によってロードさ れたライブラリをアンロードするために提供されています。 このセクションでは、以下の $ZF 関数について説明しています。 • $ZF(-6) — ユーザ指定のインデックス番号によって参照されるコールアウト・ライブラリから関数を呼び出します。ライ ブラリがまだロードされていない場合には、自動的にロードします。 • $ZF(-4,4) — インデックス番号によって指定されるコールアウト・ライブラリをアンロードします。 Caché コールアウト・ゲートウェイの使用法 27 コールアウト・ライブラリ関数の呼び出し • $ZF(-4,5) および $ZF(-4,6) — システム・インデックス・テーブル内でエントリを作成または削除します。システム・イ ンデックスは、Caché のインスタンス内のすべてのプロセスでグローバルに利用可能になります。 • $ZF(-4,7) および $ZF(-4,8) — プロセス・インデックス・テーブル内でエントリを作成または削除します。プロセス・テー ブルは、システム・テーブルの前に検索されるため、プロセス内でシステム全体の定義をオーバーライドするために 使用します。 $ZF(-6) インタフェースは、$ZF(-5) (“システム ID によるライブラリへのアクセスでの $ZF(-5) の使用” を参照) によっ て使用されるものと類似していますが、以下の点が異なります。 • $ZF(-6) を使用するには、先にライブラリ・インデックス・テーブルを作成する必要があります。ライブラリ・インデック ス値は、ユーザ定義であり、実行時に変更またはオーバーライドできます。 • ライブラリ名は、インデックス内に格納され、ライブラリをロードするアプリケーションによって定義される必要はありま せん。ライブラリ・ファイルの名前と場所は、インデックス値によって、ライブラリをロードする依存アプリケーションに 影響を与えることなくインデックス内で変更することができます。 • ライブラリをロードする別の $ZF 関数はありません。代わりに、ライブラリはその関数の一つを呼び出す最初の $ZF(-6) 呼び出しによって自動的にロードされます。 • 開発者は既にライブラリ関数 ID (ZFEntry テーブル内の順序によって決定される) を知っていると見なされるため、 指定された名前およびライブラリ・インデックス値に対して関数 ID を返す $ZF 関数はありません。 以下の例は、$ZF(-6) インタフェースの使用方法を示しています。最初の例は、システム・インデックス・テーブル内にラ イブラリ ID を定義し、2 番目の例 (別のアプリケーションから呼び出される場合がある) は、ライブラリ ID を使用してライ ブラリ関数を呼び出します。 $ZF(-4,5) および $ZF(-4,6) を使用したシステム・インデックス・エントリの定義 この例では、システム・インデックス・テーブル内で 100 を mylibrary.dll のライブラリ ID として設定します。その 番号に既に定義が存在している場合は、削除されて置き換えられます。 set LibID = 100 set status = $ZF(-4,6,LibID) // clear any old entries with this ID value set status = $ZF(-4,5,LibID,"C:\calloutlibs\mylibrary.dll") // set system ID • LibID は、開発者によって選択されたインデックス番号です。この番号は、予約済みのシステム値 1024 ~ 2047 を除くゼロよりも大きい任意の整数です。 • システム・インデックスが既にインデックス番号 100 を使用するエントリを含んでいる場合は、$ZF(-4,6) へ の呼び出しによって削除されます。インデックス・エントリは上書きできないため、推奨される方法です。 • $ZF(-4,5) への呼び出しは、インデックス番号 100 をライブラリ・ファイル mylibrary.dll に関連付けます。 ライブラリ ID がシステム・インデックス・テーブルに定義されると、Caché の現在のインスタンス内のすべてのプロセスで グローバルに利用可能になります。 $ZF(-6) を使用した関数の呼び出し この例では、前の例で作成されたシステム・インデックス・テーブルを使用します。$ZF(-6) を使用してライブラリ をロードし、ライブラリ関数を呼び出して、ライブラリをアンロードします。このコードは、システム・インデックス内 でライブラリ ID を定義したのと同じアプリケーションから呼び出す必要はありません。 set set set set • LibID = 100 // library ID in system index table FuncID = 2 // second function in library ZFEntry table x = $ZF(-6,LibID, FuncID, "arg1") // call function 2 status = $ZF(-4,4,LibID) // unload the library LibID は、システム・インデックス内に定義されているライブラリ ID です。このアプリケーションは、ライブラリ 関数を使用するためにライブラリ名またはパスを知っている必要はありません。 28 Caché コールアウト・ゲートウェイの使用法 ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 • FuncID は、ライブラリ LibID の ZFEntry テーブルにリストされている 2 番目の関数の関数 ID です。開発 者はライブラリ・コードへのアクセス権を持っていると見なされます — $ZF(-6) インタフェースは、ライブラリ 関数名を指定することによって、この番号を取得するための関数を持っていません。 • $ZF(-6) への呼び出しは、100 をライブラリ ID として指定し、2 を関数 ID として指定し、"arg1" を関数 に渡す引数として指定します。この呼び出しは、コールアウト・ライブラリ mylibrary.dll がロードされていない 場合にはロードし、ZFEntry テーブルにリストされている 2 番目の関数を呼び出します。 • $ZF(-4,4) への呼び出しは、ライブラリをアンロードします。$ZF(-6) によってロードされる各ライブラリは、プ ロセスが終了するまでまたは $ZF(-4,4) によってアンロードされるまで常駐したままになります。 4.4.1 ライブラリ関数のカプセル化での $ZF(-6) インタフェースの使用 $ZF(-5) インタフェースの例のように動作する (この章で前述した “システム ID によるライブラリへのアクセスでの $ZF(5) の使用” を参照) $ZF(-6) インタフェースの例を記述するのは簡単ですが、これは $ZF(-6) を使用した利点を示しま せん。代わりに、このセクションでは、エンド・ユーザがコールアウト・ライブラリの内容または場所について知らずにまっ たく同じタスクを実行できるようにする ObjectScript クラスを提供します。 $ZF(-5) の例は、コールアウト・ライブラリ inputlibrary.dll および outputlibrary.dll から関数を呼び出して、いくつかの実 験データを処理してグラフの描画に使用できる 2 次元の配列を生成しました。このセクションの例は、同じタスクを以下 の ObjectScript コードを使用して実行します。 • クラス User.SystemIndex — システム・インデックス・テーブル内でエントリを定義するために使用されるファイル名お よびインデックス番号をカプセル化します。 • クラス User.GraphData — 両方のライブラリから関数をカプセル化するメソッドを提供します。 • メソッド GetGraph() — User.GraphData メソッドを呼び出すエンド・ユーザ・プログラムの一部です。このメソッドのコー ドは、$ZF(-5) の例とまったく同じタスクを実行しますが、$ZF 関数を直接呼び出しません。 User.SystemIndex クラスを使用すると、コールアウト・ライブラリを使用するアプリケーションがインデックス番号またはファ イルの場所をハードコード化することなく、システム・インデックス・エントリを作成してアクセスすることができます。 ObjectScript クラス User.SystemIndex Class User.SystemIndex Extends %Persistent { /// Defines system index table entries for the User.GraphData libraries ClassMethod InitGraphData() As %Status { // For each library, delete any existing system index entry and add a new one set sc = $ZF(-4,6,..#InputLibraryID) set sc = $ZF(-4,5,..#InputLibraryID,"c:\intersystems\cache\bin\inputlibrary.dll") set sc = $ZF(-4,6,..#OutputLibraryID) set sc = $ZF(-4,5,..#OutputLibraryID,"c:\intersystems\cache\bin\outputlibrary.dll") quit 0 } Parameter InputLibraryID = 100; Parameter OutputLibraryID = 200; } • InitGraphData() メソッドは、User.GraphData のライブラリをシステム・インデックス・テーブルに追加します。 これは、Caché のインスタンスが開始されたときに自動的に呼び出され、ライブラリがインスタンス内のすべ てのプロセスで利用可能になります。 • InputLibraryID および OutputLibraryID クラス・パラメータが利用可能になり、依存アプリケーションが (以 下の例の User.GraphData の Init() メソッドによって示されているように) インデックス値をハードコード化す る必要がなくなります。 User.GraphData クラスを使用すると、エンド・ユーザが実際のコールアウト・ライブラリについて何も知らなくてもライブラ リ関数を呼び出すことができます。 Caché コールアウト・ゲートウェイの使用法 29 コールアウト・ライブラリ関数の呼び出し ObjectScript クラス User.GraphData Class User.GraphData Extends %Persistent { /// Gets library IDs and updates the system index table for both libraries. Method Init() As %Status { set InLibID = ##class(User.GraphDataIndex).%GetParameter("InputLibraryID") set OutLibID = ##class(User.GraphDataIndex).%GetParameter("OutputLibraryID") quit ##class(User.SystemIndex).InitGraphData() } Property InLibID As %Integer [Private]; Property OutLibID As %Integer [Private]; /// Calls function "FormatData" in library "inputlibrary.dll" Method FormatData(rawdata As %Double) As %String { quit $ZF(-6,..InLibID,1,rawdata) } /// Calls function "RefineData" in library "outputlibrary.dll" Method RefineData(midvalue As %String) As %String { quit $ZF(-6,..OutLibID,1,midvalue) } /// Calls function "PlotGraph" in library "outputlibrary.dll" Method PlotGraph(datapoint As %String, xvalue As %Integer) As %String { quit $ZF(-6,..OutLibID,2,datapoint,xvalue) } /// Unloads both libraries Method Unload() As %String { set sc = $ZF(-4,4,..InLibID) // unload "inputlibrary.dll" set sc = $ZF(-4,4,..OutLibID) // unload "outputlibrary.dll" quit 0 } } • Init() メソッドは、inputlibrary.dll および outputlibrary.dll のシステム・インデックス・エントリを設定または更 新する User.SystemIndex からクラス・メソッドを呼び出します。また、ライブラリ ID の現在の値も取得しま す。このクラスの開発者は引き続き、コールアウト・ライブラリ・コードについて知っている必要がありますが、 システム・インデックスへの将来の変更は透過的になります。 • メソッド FormatData()、RefineData()、および PlotGraph() はそれぞれ、1 つのライブラリ関数への呼び出し をカプセル化します。これらは無条件 $ZF 関数呼び出しのみを含むため、Caché コンパイラはこれらのメ ソッドを元の $ZF 呼び出しと同じ速さで実行するように最適化することができます。 • Unload() メソッドは、ライブラリのいずれか、または両方をアンロードします。 以下の例は、エンド・ユーザが User.GraphData 内でメソッドを使用する方法を示しています。GetGraph() メソッドは、 コールアウト・ライブラリを使用して $ZF(-5) インタフェース例内の GraphSomeData() メソッドとまったく同じタスクを実行 しますが (この章で前述している “システム ID によるライブラリへのアクセスでの $ZF(-5) の使用” を参照)、$ZF 関数 を直接呼び出しません。 メソッド GetGraph() Method GetGraph(loopsize As %Integer = 100000) As %Status { // Get an instance of class GraphData and initialize the system index set graphlib = ##class(User.GraphData).%New() set sc = graphlib.Init() // call functions from both libraries repeatedly // each library is loaded automatically on first call for count=1:1:loopsize { set midvalue = graphlib.FormatData(^rawdata(count)) set flatdata(count) = graphlib.RefineData(midvalue) } // plot results of the previous loop for count=1:1:loopsize { set x = graphlib.PlotGraph(flatdata(count),0) set y = graphlib.PlotGraph(flatdata(count),x) set ^graph(x,y) = flatdata(count) } 30 Caché コールアウト・ゲートウェイの使用法 ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用 //return after unloading all libraries loaded by $ZF(-6) set status = graphlib.Unload() quit 0 } • User.GraphData クラスは graphlib としてインスタンス化され、Init() メソッドがシステム・インデックスを初期 化するために呼び出されます。システム・インデックスは Caché のインスタンス内のすべてのプロセスに対 して初期化する必要があるのは一度のみのため、このメソッドをここで呼び出す必要はありません。 • 最初のループは、間接的に $ZF(-6) を使用して、各ライブラリから関数を呼び出し、$ZF(-6) は、各ライブ ラリを最初に必要な際に自動的にロードします。ライブラリ inputlibrary.dll は、FormatData() への最初の呼 び出しでロードされ、outputlibrary.dll は、RefineData() への最初の呼び出しでロードされます。 • 2 番目のループは、PlotGraph() を既にロードされているライブラリ outputlibrary.dll から呼び出します。 • Unload() への呼び出しは、両方のライブラリで間接的に $ZF(-4,4) を呼び出します。 4.4.2 テストでのプロセス・インデックスの使用 前に述べたように、プロセス・インデックス・テーブルは、システム・インデックス・テーブルの前に検索されるため、プロセ ス内でシステム全体の定義をオーバーライドするために使用できます。以下の例では、前のセクションで使用されたライ ブラリのうちの 1 つの新しいバージョンをテストするために使用されるプロセス・インデックスを作成します。 "inputlibrary.dll" の新しいバージョンをテストするためのプロセス・インデックスの使用 // Initialize the system index and generate output from standard library set testlib = ##class(User.GraphData).%New() set sc = testlib.Init() set sc = graphgen.GetGraph() // get 100000 data items by default merge testgraph1 = ^graph kill ^graph // create process index and test new library with same instance of testproc set sc = $ZF(-4,4,100) // unload current copy of inputlib set sc = $ZF(-4,8) // delete existing process index, if any set sc = $ZF(-4,7,100, "c:\testfiles\newinputlibrary.dll") // override system index set sc = graphgen.GetGraph() merge testgraph2 = ^graph // Now compare testdata1 and testdata2 • 前の例のように、最初の 3 行で、このテスト・コードはシステム・インデックスを初期化してグラフを生成しま す。グラフは、inputlibrary.dll の標準バージョン (ID 値 100 を持つシステム・インデックス・エントリによって 識別される) を使用してプロットされ、testgraph1 に保存されています。 • $ZF(-4,4) への呼び出しにより inputlibrary.dll がアンロードされます。これはシステム・インデックス・テーブ ル内でライブラリ ID 100 で識別されます。 • $ZF(-4,8) は、ライブラリ ID を指定せずに呼び出され、現在のプロセス・インデックス・テーブル内のすべ てのエントリが削除されることを示します。 • $ZF(-4,7) への呼び出しは、テスト・ライブラリ newinputlibrary.dll に 100 をライブラリ ID として設定するプ ロセス・インデックス・テーブルにエントリを追加します。これにより、システム・インデックス内のその ID のエ ントリがオーバーライドされます。ライブラリ ID 100 は、inputlibrary.dll ではなく newinputlibrary.dll をポイ ントするようになります。 • GetGraph() が User.GraphData の同じインスタンスを使用して再び呼び出されます。標準バージョンの inputlibrary.dll がアンロードされる以外は何も変更されないため、GetGraph() は新しいバージョンのライブ ラリをロードして使用します。その後、テストではグラフ testgraph1 と testgraph2 が比較され、両方のバー ジョンで同じ結果を生成することが確認されます。 Caché コールアウト・ゲートウェイの使用法 31 5 静的にリンクされたコールアウト関数 このドキュメント内の前の章では、実行時にロードできるスタンドアロン・コールアウト・ライブラリを作成する方法を説明し ました。ただし、コールアウト関数をカスタム・バージョンの Caché に静的にリンクして常に利用できるようにすることもで きます。関数が Caché にリンクされているため、関数を呼び出すときにコールアウト・ライブラリを明示的にロードしたり、 ライブラリを指定する必要はありません。 以下の項目について説明します。 • 静的にリンクされたコールアウト関数の呼び出し — 静的にリンクされた関数を使用する利点を説明します。 • Windows でのカスタム CACHE.EXE ファイルの作成 — Visual Studio を使用してコールアウト・コードをカスタム・ バージョンの Caché にリンクする方法を説明します。 • UNIX®、Linux、または OS-X でのカスタム CACHE.EXE ファイルの作成 — コールアウト・コードをカスタム・バージョ ンの Caché にリンクする方法を説明します。 • OpenVMS でのカスタム CZF.EXE ファイルの作成 — OpenVMS バージョンの Caché に組み込まれるコールアウト 関数の標準セットを変更する方法を説明します。静的リンクは、OpenVMS では異なる意味合いを持ちますが、同じ 利点があります。 5.1 静的にリンクされたコールアウト関数の呼び出し 静的にリンクされたコールアウト関数の呼び出し規則は、動的ライブラリの規則と異なります。以下はその例です。 $ZF(-3,"mylibrary","MYFUNC",args...) 上記は以下のようになります。 $ZF("MYFUNC",args...) 関数が静的にリンクされているため、サブ関数番号およびライブラリ名 (この例の、-3,"mylibrary" など) を指定する 必要はありません。 Caché コールアウト・ゲートウェイの使用法 33 静的にリンクされたコールアウト関数 5.2 Windows でのカスタム CACHE.EXE ファイルの作成 #define ZF_DLL 指示文を含まないという点を除いてコールアウト・ライブラリのコードと同一のコードを含む mycallouts.c という名前のファイルがあることを前提とします (“Caché コールアウト・ライブラリの作成” を参照)。これをコンパイルおよ びリンクする手順は、以下のとおりです。 外部関数のコンパイルまたはアセンブル Windows で mycallouts.c をコンパイルするには、以下のコマンドを使用します。 cl -c mycallouts.c これにより、Caché にリンク可能な mycallouts.obj という出力ファイルを生成します。 オブジェクト・ファイルと Caché オブジェクト・ファイルを、新しいバージョンの Caché にリンクします。 以下の方法で、$ZF で使用する C 関数をリンクします。 1. <install-dir>\Dev\Cache\callin ディレクトリ (<install-dir> はユーザの構成のルート・ディレクトリです) で構 築を実行するか、必要なファイルのコピーを使ってプライベート・ディレクトリを作成するかのいずれかです。 以下のファイルをリンクします。 • cache.obj • main.obj • shdir.obj • clink.bat プライベート・ディレクトリで mycallouts.c をコンパイルし、生成された mycallouts.obj ファイルにこれらの ファイルをリンクします。 2. czf.obj ファイルを mycallouts.obj に置き換えます。 3. プロジェクトを構築します。これにより、プライベート・ディレクトリに cache.exe ファイルを生成します。別々 のファイルに C 関数を配置している場合、それらを別々にコンパイルし、mycallouts.c で宣言する必要が あります。しかし、そこには組み込みません。“Unresolved externals...” というメッセージが表示された場 合、他のライブラリを組み込む必要があります。組み込むファイルについてサポートが必要な場合、インター システムズのサポート窓口までお問い合わせください。 4. <install-dir>\bin (<install-dir> はユーザの構成のルート・ディレクトリ) に現在インストールされている cache.exe のバージョンを保存します。これにより、そのファイルをリストアできます。 Caché をシャットダウンし、Caché の実行可能ファイルを新しいファイルに置き換えます。 以下の方法で、Caché を Windows に再インストールします。 1. キューブ・メニューの [Caché の停止] を使用して、Caché を停止します。 2. cache.exe ファイルをプライベート・ディレクトリから <install-dir>/bin にコピーします。<install-dir> は、ユー ザ構成のルート・ディレクトリです。 Caché を再起動すると、関数が使用可能になります。 Caché の再起動 Windows では、Caché キューブから Caché を開始します。 34 Caché コールアウト・ゲートウェイの使用法 UNIX®、Linux、または OS-X でのカスタム CACHE.EXE ファイルの作成 現在の Caché バージョンは C 関数を組み込んでいます。 以下の方法で、(Windows 上の) Caché の管理者ディレクトリにある Caché をオリジナル・バージョンに戻します。 1. Caché をシャットダウンします。 2. 保存されたオリジナルの cache.exe ファイルを <install-dir>\bin にコピーします。<install-dir> は、構成の ルート・ディレクトリです。 5.3 UNIX®、Linux、または OS-X でのカスタム CACHE.EXE ファ イルの作成 #define ZF_DLL 指示文を含まないという点を除いてコールアウト・ライブラリのコードと同一のコードを含む mycallouts.c という名前のファイルがあることを前提とします (“Caché コールアウト・ライブラリの作成” を参照)。これをコンパイルおよ びリンクする手順は、以下のとおりです。 外部関数のコンパイルまたはアセンブル mycallouts.c をコンパイルするには、以下のコマンドを使用します。 cc -c mycallouts.c オブジェクト・ファイルと Caché オブジェクト・ファイルを、新しいバージョンの Caché にリンクします。 以下の方法で、$ZF で使用する C 関数をリンクします。 1. <install-dir>/source/Cache ディレクトリで構築を実行するか、必要なファイルのコピーでプライベート・ディ レクトリを作成するかのいずれかを実行します。以下のファイルをリンクします。 • cache.o (Caché 配布キットで提供されています) • main.o (Caché 配布キットで提供されています) • shdir.o (shdir.c を手動でコンパイルする必要があります) • mycallouts.o (プライベート・ネームスペースに作成されます) 2. プロジェクトを構築します。“Unresolved externals” メッセージを受け取った場合、他のライブラリを組み込 む必要があります。組み込むファイルがわからない場合、インターシステムズのサポート窓口までお問い合 わせください。別々のファイルに C 関数を置く場合、それらを別々にコンパイルし、mycallouts.c で宣言す る必要があります。しかし、そこには組み込みません。 3. /cachesys/bin/ に (あるいは任意の場所のインストール・ディレクトリに) Caché のバージョンを保存します。 これにより、必要に応じて Caché をリストアできます。 Caché をシャットダウンし、Caché の実行可能ファイルを新しいファイルに置き換えます。 Caché 実行可能プログラムを置換するには、以下の手順に従います。 1. 以下を実行し、Caché をシャットダウンします。 ccontrol stop <configname> <configname> は、Caché のインストール名です。 2. cache ファイルをプライベート・ディレクトリから <install-dir>/bin/ にコピーします。<install-dir> は、ユーザ の構成のルート・ディレクトリです。 Caché コールアウト・ゲートウェイの使用法 35 静的にリンクされたコールアウト関数 Caché の再起動 cstart スクリプトを使用して、または以下を呼び出して Caché を開始します。 ccontrol start <configname> <configname> は、起動したい Caché のインストール名です。 以下の方法で、Caché システム管理者のディレクトリにある Caché をオリジナル・バージョンに戻します。 1. Caché をシャットダウンします。 2. 保存されたオリジナルの cache ファイルを <install-dir>/bin にコピーします。<install-dir> は、ユーザ構成 のルート・ディレクトリです。 5.4 OpenVMS でのカスタム CZF.EXE ファイルの作成 既定では、OpenVMS 用の Caché は、既にいくつかのコールアウト関数を含む CZF.EXE という名前のイメージを含みま す (標準 CZF.EXE 関数の説明は、“DSM に代わる $ZF 関数呼び出し” を参照してください)。 OpenVMS 下では (この章で説明しているその他のオペレーティング・システムとは異なり)、コールアウト・ライブラリはカ スタム・バージョンの cache.exe に静的にリンクされません。代わりに、標準バージョンの CZF.EXE をカスタム・バージョ ンと置き換えます (“Caché コールアウト・ライブラリの作成” を参照)。標準バージョンのソース・コードは、カスタム・バー ジョンがそれを含めることができるように提供されています。 CZF.C のコンパイル 外部関数と Caché にリンクする CZF.OBJ ファイルを準備するには、DCL プロンプトから以下のコマンドを発行 することによって CZF.C をコンパイルします。 $ CC CZF.C 注釈 OpenVMS のみ: CZF.M64 のアセンブル CZF.M64 ファイルを使用している場合は、この時点でアセンブルして (“CZF.M64 の使用” を参照) CZF.OBJ を作成します。 オブジェクト・ファイルのリンクによる CZF.EXE の作成 CZFBUILD.com ファイルを使用して、外部関数にリンクします。CZFBUILD.com を編集し、リンクするファイルを 追加します。編集前の CZFBUILD.com は以下のようになります。 LINK/NOTRACE/MAP=CZF/SHAREABLE=CZF SYS$INPUT:/OPTIONS CLUSTER=CZF,,,CZF GSMATCH=ALWAYS,0,0 SYMBOL_VECTOR=(ZFE=DATA) 1. CZFBUILD.COM を編集し、CZF.OBJ と各外部オブジェクト・ファイルを組み込みます。CZF ファイルで定 義した外部関数を含む各ファイル名を、CZFBUILD.COM の 2 行目に追加します。例えば、関数が abc.obj と xyz.obj という 2 つのファイルにある場合、編集後の 2 行目は以下のようになります。 CLUSTER=CZF,,,CZF,ABC,XYZ 2. DCL プロンプトで CZFBUILD.COM を実行します。これにより、CZF.EXE ファイルを生成します。 36 Caché コールアウト・ゲートウェイの使用法 OpenVMS でのカスタム CZF.EXE ファイルの作成 注釈 コードが #include "callin.h" を実行し、Caché にコールバックする場合、Caché 共有可能イメー ジにもリンクする必要があります。 • Alpha システムでは、CACHE /sharable を使用します。 • Itanium システムでは、CKERNEL /sharable を使用します。 コマンドは、コマンド行ではなく、オプション・ファイル内で発行する必要があります。 Caché のシャットダウンと CZF.EXE のインストール 以下のコマンドを発行します。 CCONTROL STOP <configname> <configname> は、シャットダウンしたい Caché のインストール名です。 Caché 実行可能プログラムを共有メモリからアンロードし、CZF.EXE を置き換える必要があります。以下はその コードです。 CCONTROL UNLOAD <configname> <configname> は、アンロードしたい Caché のインストール名です。 プライベート・ディレクトリから <install-dir>:[bin] サブディレクトリに CZF.EXE をコピーします。以下はそのコード です。 COPY CZF.EXE DKA0:[CACHESYS.BIN] Caché の再起動 Caché を再起動するには、以下のコマンドを発行します。 CCONTROL START <configname> <configname> は、起動したい Caché のインストール名です。 Caché コールアウト・ゲートウェイの使用法 37 6 UNIX® に関する特別な考慮事項 システム呼び出しの中には、open、read、write、close、ioctl、pause などのシグナルをプロセスが受け取ると、失敗するも のがあります。 関数がこれらのシステム呼び出しを使用する場合、実際のエラー、Ctrl-C、再起動を必要とする呼び出しと区別できるよ うに、注意してコードを記述する必要があります。生成された小規模な関数セットにより、非同期イベントのチェックや、 $ZF に新規のアラーム・ハンドラを設定できます。 6.1 その他のコールアウト・シグナル処理 関数の宣言は、cdzf.h に組み込まれます。 • int sigrtclr(); — 再試行フラグを消去します。sigrtchk() を使用する前に一度呼び出す必要があります。 • int dzfalarm(); — 新規 SIGALRM ハンドラを構築します。 $ZF にエントリする際に、前のハンドラが自動的に保存されます。終了すると、自動的にリストアされます。ユーザ・ プログラムで、他のシグナル処理を変更しないでください。 • int sigrtchk(); — 非同期イベントをチェックします。これは、open、close、read、write、ioctl、または pause の いずれかのシステム呼び出しが失敗した場合や、プロセスがシグナルを受け取ったときに失敗する呼び出しがある 場合に、必ず呼び出す必要があります。ユーザの次の動作を示すコードを返します。 – -1 — シグナルではありません。入出力エラーを調べてください。errno 変数の内容を参照してください。 – 0 — 他のシグナルです。割り込みが生じた時点から処理を再開してください。 – 1 — SIGINT/SIGTERM。SIGTERM "return 0" で $ZF を終了します。Caché は、これらのシグナルを適切に取 得します。 デバイスを制御する通常の $ZF 関数は、以下のように記述します。 if ((fd = open(DEV_NAME, DEV_MODE)) < 0) { Set some flags Call zferror return 0; } プロセスがシグナルを受け取ると、open システム呼び出しは失敗する可能性があります。通常、これはエラーではない ため、処理を再開できます。しかし、シグナルによっては他の処理が必要な場合もあります。すべての可能性を考慮す るために、以下の C コードを使用することを検討してください。 Caché コールアウト・ゲートウェイの使用法 39 UNIX® に関する特別な考慮事項 sigrtclr(); while (TRUE) { if (sigrtchk() == 1) return 1 or 0; if ((fd = open(DEV_NAME, DEV_MODE)) < 0) { switch (sigrtchk()) { case -1: /* This is probably a real device error */ Set some flags Call zferror return 0; case 0: /* A innocuous signal was received. Restart. */ continue; case 1: /* Someone is trying to terminate the job. */ Do cleanup work return 1 or 0; } } else break; } /* Code to handle the normal situation: open() system call succeeded */ dzfalarm 経由の場合を除き、シグナル・ハンドラを設定してはいけません。 40 Caché コールアウト・ゲートウェイの使用法 7 OpenVMS に関する特別な考慮事項 $ZF を使用して、OpenVMS システム・サービスを呼び出すことができます。CZF.M64 という名前のファイルにある、Caché ObjectScript 以外の各ルーチンにインタフェースを定義します。また、$ZF を使用して、OpenVMS システム・サービス・ ルーチンを呼び出し、DCL コマンド・プロシージャやその他の高水準言語のルーチンを呼び出すこともできます。 以下の項目について説明します。 • CZF.M64 の使用 — コールアウト・コードの作成では C が優先言語ですが、.M64 マクロ・ファイルを使用することも できます。 • 特権レベルを上げる ZFPRIV の使用 — コールアウト関数に呼び出し元の通常の特権レベルだけでなく、SHARE 以外のすべての特権を与える ZFPRIV 文について説明します。 • システム・サービスでの V リンクの使用 — "v" リンク・タイプで OpenVMS 記述子を渡すことによって、OpenVMS シ ステム・サービスおよびライブラリ・ルーチンを呼び出す方法を説明します。 • DSM に代わる $ZF 関数呼び出し — OpenVMS システムに付属している組み込み CZF.EXE コールアウト・ライブラ リのコンテンツを説明します。 7.1 CZF.M64 の使用 コールアウト・コードを記述する優先言語は C ですが (“Caché コールアウト・ライブラリの作成” で説明されているように CZF.C ファイルを作成)、マクロ・ファイル (CZF.M64) を使用することもできます。C コンパイラがある場合、CZF.C を使用 します。それ以外の場合、CZF.M64 を使用します。両方を使用することができません。 CZF.M64 ファイルを使用する際は、.SHOW コマンドと .END コマンドの間に、ZFENTRY 文のみを入力します。この文 は、以下の形式にする必要があります。 ZFENTRY CALLNAME=name,LINKNAME=fname,ARGS=atype,PRIVS=priv • CALLNAME — $ZF 関数呼び出しで、Caché が外部関数を呼び出す名前です。 • LINKNAME — ユーザ記述の外部関数のエントリ・ポイント名です。CZF.C で使用する ZFENTRY 文のエントリ・ポイ ント引数に相当します。 • ARGS— どのように引数を渡すかを記述した文字列です。CZF.C で使用する ZFENTRY 文の argtypes 引数に相当 します (“ZFENTRY の argtypes” を参照)。 構造体と引数のプロトタイプ定義は、インクルード・ファイル cdzf.h にあります。インターシステムズの追加の内部定 義もまた、ここで宣言されています。 Caché コールアウト・ゲートウェイの使用法 41 OpenVMS に関する特別な考慮事項 • PRIVS — 関数を上位特権レベルで実行させるには、“YES” を入力します。呼び出し関数と同じ特権レベルで関数 を実行させるには、“NO” を入力します。 呼び出し形式が異なっても、これは C プログラムで使用される ZFENTRY 文と基本的に同じです (“ZFEntry テーブル の作成” を参照)。 CZF.M64 のアセンブル CZF.M64 をアセンブルするため、以下のコマンドを DCL プロンプトから発行します。 $ MAC /ALPHA CZF.M64 7.2 特権レベルを上げる ZFPRIV の使用 ZFENTRY 文は、呼び出しプロセスの特権レベルで実行します。これに SHARE 特権以外のすべての特権を与える場 合、ZFPRIV 文で外部関数を記述することができます。ZFPRIV 文は、名前と以下の引数リストの最後に追加されている 引数 "privileges" 以外は、ZFENTRY 文と同じ形式です。 ZFPRIV("name","argtypes",entrypoint,privileges) privileges 引数は、以下のいずれかになります。 • PRIV — 関数は上位特権レベルで実行します。 • NOPRIV — 関数は、呼び出しプロセスの特権レベルで実行します。 czf.c ファイルを OpenVMS とその他のシステム (例えば、UNIX® および NT) 間で変更せずに移動できるようにするた めに、これらのマクロには以下の効果があります。 • OpenVMS の ZFENTRY では、呼び出し元の通常の特権レベルで実行する $ZF 関数を定義します。これは、$ZF 関数が UNIX® で動作する方法です。 • ZFPRIV では、プログラマが $ZF 関数を呼び出し元の特権レベルで実行するか、またはプロセスが Caché 内で持 つ上位特権レベル (SHARE 以外のすべての特権) で実行するかを指定できます。UNIX® では、すべての $ZF 関 数が呼び出し元のレベルで実行されるため、この関数は ZFENTRY と同一です。 7.3 71 システム・サービスでの V リンクの使用 OpenVMS システム・サービスとライブラリ・ルーチンの呼び出しに対応するため、OpenVMS 記述子を "v" リンク・タイプ を使用して渡すことができます。 struct dsc$descriptor s * v V OpenVMS のみ: OpenVMS システム・サービスを呼び出すときに 使用します。 ZF_FAILURE および ZF_SUCCESS の実装返り値は、プラットフォームによって異なります。これは一般的なシステム呼 び出しに対応するためです。UNIX® では、返り値がゼロの場合は成功と考えられ、ゼロ以外の場合は失敗です。OpenVMS では、奇数値の場合に成功と考えられ、偶数値は失敗と考えられます。実際の失敗値は、Caché ObjectScript プログラ マには提供されません。これは、^SYSLOG ユーティリティを使用して調査することができます。 この例では、OpenVMS 関数 LIB$TRIM_FILESPEC を Caché ObjectScript に公開します。ObjectScript から、次の呼び 出しが使用可能になります。 SET newfilespec=$ZF("TRIM FILESPEC",oldfilespec,width) 42 Caché コールアウト・ゲートウェイの使用法 DSM に代わる $ZF 関数呼び出し 次のように ZENTRY マクロを使用して単純に定義できれば便利です。 ZFENTRY("TRIM_FILESPEC", "vVp", LIB$TRIM_FILESPEC) 残念ながら、CZF インタフェースは 32 の実パラメータをそれが呼び出すすべての関数に渡します。32 の実パラメータ よりも少ない場合は、それらのパラメータに対して NULL が渡されます。LIB$TRIM_FILESPEC は、多くのライブラリお よびシステム関数と同様に実パラメータの数をカウントするため、簡単なラッパ関数を提供する必要があります。 #ifdef __VMS ZFENTRY("TRIM_FILESPEC","viV",trim_filespec) #endif 簡単なラッパ関数は次のとおりです。 関数 trim_filespec #ifdef __VMS int trim_filespec(struct dsc$descriptor_s*oldfilespec,int width,struct dsc$descriptor_s*newfilespec){ short int resultwidth; int s; if(width> ZFString)return ZF_FAILURE; s= LIB$TRIM_FILESPEC(oldfilespec,newfilespec,&width,&resultwidth); newfilespec->dsc$w_length= resultwidth; return s; } #endif 7.4 DSM に代わる $ZF 関数呼び出し このセクションでは、DSM VMS システム・サービスの Zcall 関数をエミュレートするための $ZF 関数の引数として提供で きる、Caché 提供の (内部) 関数について説明します。これらの関数は、標準 CZF.EXE コールアウト・イメージに含まれ ます。このイメージのカスタマイズの詳細は、“OpenVMS でのカスタム CZF.EXE ファイルの作成” を参照してください。 以下の内部関数について説明します。 • GETJPI — ジョブおよびプロセス情報を取得します。 • GETDVI — デバイス特性を取得します。 • GETSYI — システム情報を取得します。 • SETSYM — DCL シンボル値を設定します。 • GETSYM — DCL シンボル値を返します。 • DELSYM — DCL シンボル値を削除します。 • CRELOG — 論理名を作成します。 • TRNLNM — 論理名を変換します。 • DELLOG — 論理名を削除します。 • GETUAI — アカウントの承認パラメータを返します。 • GETMSG — ステータス・コードのメッセージ・テキストを返します。 • SETPRN — 呼び出しプロセスの名前を設定します。 • SETPRI — プロセスのベース優先度を設定します。 • OPCOM — オペレータにメッセージを送信します。 • MOUNT — デバイスをマウントします。 Caché コールアウト・ゲートウェイの使用法 43 OpenVMS に関する特別な考慮事項 • DISMOUNT — デバイスをディスマウントします。 • DIRECTORY — 既定のディレクトリを返します。 • PARSE — ファイル名を解析します。 • GETFILE — ファイル情報を返します。 7.4.1 $ZF 内部関数 内部関数はすべて、関数名とその後に続くその他のパラメータのみを指定することによって $ZF で呼び出すことができ ます。以下は、GETUAI を関数として使用する例です。 SET x = $ZF("GETUAI","FRED","USERNAME") 注釈 ここでは、関数名はすべて大文字で表記されていますが、実際には大文字と小文字は区別されません。 7.4.1.1 GETJPI ジョブおよびプロセス情報を返します。 SET x = $ZF("GETJPI",pid,item) SET x = $ZF("GETJPI",procname,item) パラメータ : • pid — プロセス ID (10 進数) • item — 返すプロセス情報の項目コード • procname — プロセス名 (pid の代わりに使用) GETJPI の項目コード ACCOUNT DFPFC IMAGECOUNT PHDFLAGS TMBU APTCNT DFWSCNT IMAGNAME PID TQCNT ASTACT DIOCNT IMAGPRIV PPGCNT TQLM ASTCNT DIOLM JOBPRCCNT PRCCNT TT_ACCPORNAM ASTEN DIRIO JOBTYPE PRCLM TT_PHYDEVNAM ASTLM EFCS LOGINTIM PRCNAM UAF_FLAGS AUTHPRI EFCU MASTER_PID PRI UIC AUTHPRIV EFWM MAXDETACH PRIB USERNAME BIOCNT ENQCNT MAXJOBS PROC_INDEX VIRTPEAK BIOLM ENQLM MEM PROCPRIV VOLUMES BUFIO EXCVEC MODE SCHED_POLICY VP_CONSUMER BYTCNT FAST_VP_SWITCH MSGMASK SHRFILLM VP_CPUTIM BYTLM FILCNT NODENAME SITESPEC WSAUTH CLINAME FILLM NODE_CSID SLOW_VP_SWITCH WSAUTHEXT 44 Caché コールアウト・ゲートウェイの使用法 DSM に代わる $ZF 関数呼び出し CPU_ID FINALEXC NOD_VERSION STATE WSEXTENT CPULIM FREP0VA OWNER STS WSPEAK CPUTIM FREP1VA PAGEFLTS STS2 WSQUOTA CREPRC FREPTECNT PAGFILCNT SWPFILLOC WSSIZE FLAGS GPGCNT PAGFILLOC TABLENAME CURPRIV GRP PGFLQUOTA TERMINAL 7.4.1.2 GETDVI デバイス特性を返します。 SET x = $ZF("GETDVI",devname,item,flag) パラメータ : • devname — 物理デバイス名、または物理デバイス名と同等の論理デバイス名 • item — 返すデバイス情報の項目コード • flag — 1 は 1 次的な特性、2 は 2 次的な特性、既定値は 2 です。 GETDVI の項目コード ACPTYPE EXISTS PID TT_AUTOBAUD TT_MODHANGUP ALL FOD RCK TT_AVO TT_NOBRDCST ALLDEVNAM FOR RCT TT_BLOCK TT_NOECHO ALLOCLASS FREEBLOCKS REC TT_BRDCSTMBX TT_NOTYPEAHD ALT_HOST_AVAIL FULLDEVNAM RECSIZ TT_CRFILL TT_OPER ALT_HOST_NAME GEN REFCNT TT_DECCRT TT_PAGE ALT_HOST_TYPE HOST_AVAIL REMOTE_DEVICE TT_DECCRT2 TT_PASTHRU AVL HOST_COUNT RND TT_DIALUP TT_PHYDEVNAM CCL HOST_NAME ROOTDEVNAM TT_DISCONNECT TT_PRINTER CLUSTER HOST_TYPE RTM TT_DMA TT_READSYNC CONCEALED IDV SDI TT_DRCS TT_REGIS CYLINDERS LOCKID SECTORS TT_EDIT TT_REMOTE DEVBUFSIZ LOGVOLNAM SERIALNUM TT_EDITING TT_SCOPE DEVCHAR MAXBLOCK SERVED_DEVICE TT_EIGHTBIT TT_SECURE DEVCHAR2 MAXFILES SHR TT_ESCAPE TT_SETSPEED DEVCLASS MBX SPL TT_FALLBACK TT_SIXEL DEVDEPEND MEDIA_ID SPLDEVNAM TT_HALFDUP TT_SYSPWD DEVDEPEND2 MEDIA_NAME SQD TT_HANGUP TT_TTSYNC Caché コールアウト・ゲートウェイの使用法 45 OpenVMS に関する特別な考慮事項 DEVLOCKNAM MEDIA_TYPE STS TT_HOSTSYNC TT_WRAP DEVNAM MNT SWL TT_INSERT UNIT DEVSTS MOUNTCNT TRACKS TT_LFFILL VOLCOUNT DEVTYPE NET TRANSCNT TT_LOCALECHO VOLNAM DIR NEXTDEVNAM TRM TT_LOWER VOLNUMBER DMT ODV TT_ACCPORNAM TT_MBXDSABL VOLSETMEM DUA OPCNT TT_ALTYPEAHD TT_MECHFORM VPROT ELG OPR TT_ANSICRT TT_MECHTAB WCK ERRCNT OWNUIC TT_APP_KEYPAD TT_MODEM 7.4.1.3 GETSYI システム情報を返します。 SET x = $ZF("GETSYI",item,csid[,nodename]) パラメータ : • item — 引用符付きの文字列として指定される、返すシステム・パラメータ値の項目キーワード・コード • csid — 情報を取得するクラスタ・メンバのノード CSID (クラスタ・ノード ID) パラメータ。 すべてのクラスタ・ノードを検索する場合は -1 を指定します。csid に-1 を指定した以降の各呼び出しで は、クラスタ内の次のノードの item キーワード情報が返されます。すべてのノードの順次処理が完了する と、空文字列 ("") が返されます。csid に -1 以外の値を指定すると、ノードへの順次アクセスが終了しま す。 オプションの nodename パラメータを指定する場合は (プレースホルダとして) 0 を指定します。 • nodename — オプション — 引用符付きの文字列として指定されるクラスタ・ノード。クラスタ・ノードは nodename または csid によって指定できます。クラスタ・ノードを nodename によって指定するときは、csid に値 0 を指 定します。 46 Caché コールアウト・ゲートウェイの使用法 DSM に代わる $ZF 関数呼び出し GETSYI の項目コード ACTIVECPU_CNT CLUSTER_FTIME FREE_GBLPAGES PAGEFILE_FREE PQL_MFILLM ARCHFLAG CLUSTER_MEMBER FREE_GBLSECTS PAGEFILE_PAGE PQL_MENQLM ARCH_NAME CLUSTER_NODES GBLPAGES PQL_DWSDEFAULT SCSNODE ARCH_TYPE CLUSTER_QUORUM GBLPAGFIL PQL_DWSEXTENT SPTREQ AVAILCPU_CNT CPU GBLSECTIONS PQL_DWSQUOTA SRPCOUNTV BALSETCNT CONTIG_GBLPAGES LOCKIDTBL PQL_MWSDEFAULT SWAPFILE_FREE BJOBLIM CPUTYPE LOCKIDTBL_MAX PQL_MWSEXTENT SWAPFILE_PAGE BOOTTIME DECIMAL_EMULATED MAXPROCESSCNT PQL_MWSQUOTA VERSION CHARACTER_EMULATED D_FLOAT_EMULATED MAXSYSGROUP PQL_MASTLM VIRTUALPAGECNT CLUSTER_EVOTES HW_MODEL NODENAME PQL_MBYTLM WSMAX CLUSTER_FSYSID HW_NAME NODE_CSID PQL_MDIOLM 7.4.1.4 SETSYM 特定の値に DCL シンボルを設定します。DCL シンボルはローカル、グローバルのどちらでもかまいません。SETSYM は NULL 文字列を返します。 SET x = $ZF("SETSYM",symbol,value,flag) パラメータ : • symbol — 設定する DCL シンボル • value — DCL シンボルの値 • flag — 1 はローカル、2 はグローバル、既定値は 1 です。 7.4.1.5 GETSYM 指定された DCL シンボルの値を返します。DCL シンボルはローカル、グローバルのどちらでもかまいません。flag 値の 1 を使用して、シンボル・タイプを決定できます。DCL 値は、SETSYM 関数によって設定されます。 SET x = $ZF("GETSYM",symbol[,flag]) パラメータ : • symbol — 値を返す DCL シンボル • flag — オプション — ブーリアン値。1 を指定すると、未定義シンボルには 0、ローカル・テーブルには 1、 グローバル・テーブルには 2 を返します。0 を指定すると、シンボル値を返します。既定値は 0 です。 7.4.1.6 DELSYM 指定された DCL シンボルの値を削除します。DCL シンボルはローカル、グローバルのどちらでもかまいません。DCL 値は、SETSYM 関数によって設定されます。 SET x = $ZF("DELSYM",symbol,flag) Caché コールアウト・ゲートウェイの使用法 47 OpenVMS に関する特別な考慮事項 パラメータ : • symbol — 削除する DCL シンボル • flag — 1 はローカル、2 はグローバル、既定値は 1 です。 7.4.1.7 CRELOG 指定されたモードの指定された論理名テーブルに論理名を作成します。既定では、type=USER モードおよび table= プ ロセスの論理名テーブルです。CRELOG は NULL 文字列を返します。 SET x = $ZF("CRELOG",logname,value[,type[,table]]) パラメータ : • logname — 作成する論理名 • value — 論理名と同等の文字列 • type — オプション — 定義するテーブル・モード。使用できる値の詳細は以下のとおりです。既定は USER モード。 • table — オプション — ユーザ定義の論理名テーブルの名前。type=TABLE の場合、table 値が必要です。 既定はプロセスの論理名テーブル。 使用可能な type の値は、以下のとおりです。 • USER = プロセス・テーブル/USER モード • SUPERVISOR または PROCESS = プロセス・テーブル/Supervisor モード • JOB = ジョブ・テーブル — LNM$JOB • GROUP = グループ・テーブル — LNM$GROUP • SYSTEM = システム・テーブル — LNM$SYSTEM • TABLE = ユーザ定義の論理名テーブルの名前 7.4.1.8 TRNLNM 論理名を変換し、同等の名前文字列または要求された属性を返します。一致が検出されない場合、TRNLNM は NULL 文字列を返します。 SET x = $ZF("TRNLNM",logname,table,index,acmode,trans,item) パラメータ : • logname — 変換する論理名 • table — ユーザ定義の論理名テーブルの名前。既定はプロセスの論理名テーブル。 • index — 複数変換の場合の論理名のインデックス • acmode — アクセス・モード。使用可能な値は、USER、SUPERVISOR、EXECUTIVE、および KERNEL。 • trans — 大文字/小文字変換のタイプ。利用可能な値は CASE_BLIND および CASE_SENSITIVE。 • item — 返す論理名に関する情報のタイプ。使用可能な値は、ACCESS_MODE、CONCEALED、CONFINE、 CRELOG、LENGTH、MAX_INDEX、NO_ALIAS、TABLE、TABLE_NAME、TERMINAL、および VALUE。 48 Caché コールアウト・ゲートウェイの使用法 DSM に代わる $ZF 関数呼び出し 7.4.1.9 DELLOG 指定された論理名テーブルの論理名を削除します。 SET x = $ZF("DELLOG",logname,type,table) パラメータ : • logname — 削除する論理名 • type — 論理名のタイプ • table — ユーザ定義の論理名テーブルの名前。既定はプロセスの論理名テーブル。 7.4.1.10 GETUAI 特定の OpenVMS アカウントの承認パラメータの値を返します。 SET x = $ZF("GETUAI",account,item) パラメータ : • account — アカウント名 • item — 項目コード GETUAI の項目コード ACCOUNT DFWSCNT LASTLOGIN_N PGFLQUOTA UIC ASTLM DIOLM LGICMD PRCCNT USERNAME BIOLM ENQLM MAXACCTJOBS PRI WSEXTENT BYTLM FILLM MAXDETACH PRIV WSQUOTA DEFDEV FLAGS MAXJOBS QUEPRI DEFDIR JTQUOTA OWNER SHRFILLM DEF_PRIV LASTLOGIN_I PBYTLM TQCNT 7.4.1.11 GETMSG 指定されたステータス・コードに対応するメッセージ・テキストを返します。 SET x = $ZF("GETMSG",code) パラメータ : • code — エラーのステータス・コード 7.4.1.12 SETPRN 呼び出し元のプロセスの名前を、指定された OpenVMS プロセス名に設定します。 SET x = $ZF("SETPRN",pname) パラメータ : • pname — 有効な OpenVMS プロセス名 Caché コールアウト・ゲートウェイの使用法 49 OpenVMS に関する特別な考慮事項 7.4.1.13 SETPRI 指定されたプロセスのベース優先度を設定します。対象プロセスは CACHE イメージを実行している必要があります。 SET x = $ZF("SETPRI",pri,pid) パラメータ : • pri — 0 から 15 までの整数 (0 と 15 を含む) で指定されるプロセスのベース優先度 • pid — プロセス ID (10 進数) 7.4.1.14 OPCOM 指定されたメッセージをオペレータのターミナルに送信します。その結果、NULL 文字列を返します。 SET x = $ZF("OPCOM",msg) パラメータ : • msg — オペレータのターミナルに送信するメッセージ文字列 7.4.1.15 MOUNT 指定されたデバイスをマウントします。この関数は、LIB$SPAWN を呼び出して、DCL コマンドの MOUNT を発行します。 SET x = $ZF("MOUNT",devnam,label,options,lognam) パラメータ : • devnam — デバイス名 • label — デバイス・ラベル • options — DCL ディクショナリに指定されている 1 つ以上のマウント・オプション • lognam — デバイスに割り当てる論理名 7.4.1.16 DISMOUNT 指定されたデバイスをディスマウントします。この関数は、LIB$SPAWN を呼び出して、DCL コマンドの DISMOUNT を 発行します。 SET x = $ZF("DISMOUNT",devnam,options) パラメータ : • devnam — デバイス名 • options — DCL ディクショナリに指定されている 1 つ以上のディスマウント・オプション 7.4.1.17 DIRECTORY 現在の OpenVMS 既定ディレクトリを返します。また、オプションとして、OpenVMS 既定ディレクトリを指定されたディレク トリに設定します。 SET x = $ZF("DIRECTORY",dir) 50 Caché コールアウト・ゲートウェイの使用法 DSM に代わる $ZF 関数呼び出し パラメータ : • dir — 新しいディレクトリ名 7.4.1.18 PARSE 指定されたファイル名を解析し、解析されたファイル名を返します。PARSE は RMS $PARSE サービスを呼び出します。 SET x = $ZF("PARSE",filename,defname,relname,keyword,flag) パラメータ : • filename — 解析するファイル名 • defname — 既定のファイル名 • relname — 関連付けられたファイル名 • keyword — 解析されたファイル名から返すフィールド値を指定します。使用可能な値は、NODE、DEVICE、 DIRECTORY、NAME、TYPE、および VERSION。 • flag — I/O チェックを行うかどうかを指定するフラグ。1 は I/O チェックを行いません、0 は I/O チェック を行います。既定値は 0 です。 7.4.1.19 GETFILE 指定されたファイルに関する情報を返します。この関数は、同じキーワードを使用して、F$FILE_ATTRIBUTES 字句関 数をエミュレートします。GETFILE は、OpenVMS の標準フォーマットで UIC を返し、True を 1、False を 0 として返し ます。 SET x = $ZF("GETFILE",filename,keyword) パラメータ : • filename — ファイルの名前 • keyword — 対象ファイルから返す属性を指定します。 GETFILE のキーワード ALQ DEQ GBC NOK RVN BDT DID IBS ORG SIZ BKS DVI LRL PRO UIC BLS EDT LVL PVN WCK CBT EOF MBM RAT CDT FID MRN RCK CTG FSZ MRS RDT DBS GRP NOA RFM Caché コールアウト・ゲートウェイの使用法 51 8 Caché コールアウトのクイック・リファレンス Caché $ZF() 関数は、1 つまたは 2 つの数値引数によって識別される従属関数のセットを提供します (例えば、$ZF(-1) 従属関数は外部プログラムまたはシステム・コマンドを実行し、$ZF(-4,1) 従属関数はコールアウト・ライブラリをロードし ます)。以下のリストは、特有の $ZF() 従属関数を識別する引数のみを示しています。これら関数の大半も、各関数の詳 細エントリに記述されているように追加の引数を取ります。 関数の詳細な説明は、以下の見出しの下に構成されています。 • 静的にリンクされた関数の使用 – • • • $ZF() (従属関数引数なし) — Caché の現在のインスタンスに静的にリンクされているコールアウト関数を呼び出 します。 プログラムまたはシステム・コマンドの実行 – $ZF(-1) — 作成された子プロセスとしてプログラムやシステム・コマンドを実行し、子プロセスの返信を待機しま す。 – $ZF(-2) — 作成された子プロセスとしてプログラムまたはシステム・コマンドを実行し、すぐに返します。 インデックスなしのコールアウト・ライブラリの使用 – $ZF(-3) — コールアウト・ライブラリをロードし、ライブラリ関数を呼び出します。 – $ZF(-4,1) — 名前によって指定されるコールアウト・ライブラリをロードし、それに対する ID 値を返します。 – $ZF(-4,2) — ID 値によって指定されるコールアウト・ライブラリをアンロードするか、またはすべてのライブラリを アンロードします。 – $ZF(-4,3) — 指定されたライブラリ内の関数の ID 値を返します。 – $ZF(-5) — システム定義の ID 値によって参照されるコールアウト・ライブラリから関数を呼び出します。 インデックス付きのコールアウト・ライブラリの使用 – $ZF(-4,4) — インデックス番号によって指定されるコールアウト・ライブラリをアンロードします。 – $ZF(-4,5) — コールアウト・システム・インデックス・テーブル内でエントリを作成します。 – $ZF(-4,6) — コールアウト・システム・インデックス・テーブル内でエントリを削除します。 – $ZF(-4,7) — コールアウト・プロセス・インデックス・テーブル内でエントリを作成します。 – $ZF(-4,8) — コールアウト・プロセス・インデックス・テーブル内でエントリを削除します。 – $ZF(-6) — ユーザ指定のインデックス番号によって参照されるコールアウト・ライブラリから関数を呼び出します。 Caché コールアウト・ゲートウェイの使用法 53 Caché コールアウトのクイック・リファレンス 8.1 静的にリンクされた関数の使用 関数が Caché と静的にリンクされると (“静的にリンクされたコールアウト関数” の説明を参照)、コールアウト・ライブラリ をロードしたりライブラリ名または識別子を指定したりする必要なく直ちに $ZF() で利用可能になります。 $ZF() 静的にリンクされた関数を呼び出します。別のコールアウト・ライブラリをロードおよび識別する必要がないため、 従属 $ZF 関数呼び出しは必要ありません。 retval = $ZF(func_name[, arg1[, ...argN]]) retval = $ZF(func_id[, arg1[, ...argN]]) パラメータ : • func_name — ZFEntry テーブルに指定されているライブラリ関数の名前 (“ZFEntry テーブルの作成” を 参照)。 • func_id — ZFEntry テーブル内のライブラリ関数のシーケンス番号。この番号が既知の場合は、アクセスを 速くするために関数名の代わりに使用されます (エントリは 1 から連番で番号が付けられます)。 • args — (オプション) ライブラリ関数で必要とされる引数を含むコンマ区切りリスト。 これは、以下を返します。 • retval — ライブラリ関数の出力値、またはライブラリ関数が出力値を設定しない場合は NULL。 関連項目 : “Caché コールアウト・ライブラリの作成”、“静的にリンクされたコールアウト関数”、"OpenVMS のみ: DSM に 代わる $ZF 関数呼び出し" 8.2 プログラムまたはシステム・コマンドの実行 このセクション内の $ZF 関数は、子プロセス内の外部プログラムまたはシステム・コマンドを実行するため、またはオペ レーティング・システム・シェルを起動するために使用されます。これらは、コールアウト・ライブラリなしで使用できる $ZF 関数です (“Caché コールアウト・ライブラリの作成” を参照)。 $ZF(-1) 作成された子プロセスとしてプログラムやオペレーティング・システム・コマンドを実行し、子プロセスの返信を待 機する間、現在のプロセスの実行を一時停止します。 status = $ZF(-1, oscommand) 以下の追加シグニチャは、OpenVMS でのみ有効です。 status = $ZF(-1, oscommand, outdev) status = $ZF(-1, oscommand, , indev) status = $ZF(-1, oscommand, outdev, indev) パラメータ : • oscommand — (オプション) 子プロセスとして実行されるコマンドを含む引用符付きの文字列。oscommand を指定しない場合は、オペレーティング・システム・シェルが起動されます。 54 Caché コールアウト・ゲートウェイの使用法 インデックスなしのコールアウト・ライブラリの使用 • outdev — (オプション、OpenVMS のみ) 出力デバイス。子プロセスに対して SYS$OUTPUT を指定するため に使用します。指定されていない場合、現在の SYS$OUTPUT を使用します。 • indev — (オプション、OpenVMS のみ) 入力デバイス。子プロセスに対して SYS$INPUT を指定するために 使用します。指定されていない場合、現在の SYS$INPUT を使用します。 これは、以下を返します。 • status — 作成されたプロセスからのステータス情報。作成されたプロセスの完了時に、終了ステータス・コー ドとして返されます。 – 0 — 呼び出しが正常に行われました – 1 — 子プロセスがエラーを返しました – -1 — 子プロセスを作成できませんでした 関連項目 : “$ZF(-1) を使用したシステム・コマンドの発行” の詳細と例、"Caché ObjectScript リファレンス" の $ZF(-1) の エントリ。 $ZF(-2) 作成された子プロセスとしてプログラム、またはコマンドを実行し、すぐに返します。作成された子プロセスの完 了を待たないので、そのプロセスからのステータス情報は受信できませんが、子プロセスが正常に作成されか どうかを示すステータス・コードを返します。 status = $ZF(-2, oscommand) パラメータ : • oscommand — (オプション) 子プロセスとして実行されるコマンドを含む引用符付きの文字列。oscommand を指定しない場合は、オペレーティング・システム・シェルが起動されます。 これは、以下を返します。 • status — 子プロセスが正常に作成されたかどうかを示すステータス・コード。 – 0 — 呼び出しが正常に行われました – -1 — 子プロセスを作成できませんでした 関連項目 : “$ZF(-2) を使用した同時子プロセスの作成” の詳細と例、"Caché ObjectScript リファレンス" の $ZF(-2) の エントリ。 8.3 インデックスなしのコールアウト・ライブラリの使用 これらの $ZF 関数を使用すると、Caché コールアウト共有ライブラリをロードして実行時にライブラリ関数を呼び出すこと ができます。ライブラリおよびライブラリ関数は名前で識別されます。 Caché コールアウト・ゲートウェイの使用法 55 Caché コールアウトのクイック・リファレンス $ZF(-3) コールアウト・ライブラリをロードし、ライブラリ関数を実行します。一度にロードできるのは 1 つの $ZF(-3) ライ ブラリのみです。$ZF(-3) への呼び出しで、前の呼び出しとは異なるライブラリを指定する場合、前のライブラリ はアンロードされ、置き換えられます。 retval = $ZF(-3, lib_name, func_name[, arg1[, ...argN]]) retval = $ZF(-3, lib_name, func_id[, arg1[, ...argN]]) パラメータ : • lib_name — ZFEntry テーブルに示されているコールアウト・ライブラリの名前 (“ZFEntry テーブルの作成” を参照)。ライブラリが既に前の $ZF(-3) への呼び出しによってロードされている場合は、空の文字列 ("") で現在のライブラリを使用することを指定します。 • func_name — コールアウト・ライブラリ内で検索する関数の名前。 • func_id — ZFEntry テーブル内のライブラリ関数のシーケンス番号。この番号が既知の場合は、アクセスを 速くするために関数名の代わりに使用されます (エントリは 1 から連番で番号が付けられます)。 • args — (オプション) ライブラリ関数で必要とされる引数を含むコンマ区切りリスト。 これは、以下を返します。 • retval — ライブラリ関数の出力値、またはライブラリ関数が出力値を設定しない場合は NULL。 関連項目 : “単純なライブラリ関数呼び出しでの $ZF(-3) の使用” の詳細と例。 $ZF(-4, 1) 名前によって指定されるコールアウト・ライブラリをロードし、それに対する ID 値を返します。 lib_id = $ZF(-4,1, lib_name) パラメータ : • lib_name — ロードされるコールアウト・ライブラリの名前。 これは、以下を返します。 • lib_id — lib_name を参照するために使用されるシステム定義識別子。 関連項目 : “システム ID によるライブラリへのアクセスでの $ZF(-5) の使用” の詳細と例。 $ZF(-4, 2) ID 値によって指定されるコールアウト・ライブラリをアンロードします。ID が指定されていない場合は、$ZF(-4,1) によってロードされたすべてのライブラリがアンロードされます。$ZF(-3) によってロードされたライブラリはアン ロードされません。 $ZF(-4,2[,lib_id]) パラメータ : • lib_id — $ZF(-4,1) によって返されるシステム定義識別子。指定されていない場合は、$ZF(-4,1) によって ロードされたすべてのライブラリがアンロードされます。 関連項目 : 56 Caché コールアウト・ゲートウェイの使用法 インデックス付きのコールアウト・ライブラリの使用 "システム ID によるライブラリへのアクセスでの $ZF(-5) の使用" の詳細と例。 $ZF(-4, 3) 指定されたコールアウト・ライブラリ内の関数の ID 値を返します。 func_id = $ZF(-4,3, lib_id, func_name) パラメータ : • lib_id — $ZF(-4,1) によって返されるシステム定義識別子。 • func_name — コールアウト・ライブラリ内で検索する関数の名前。 これは、以下を返します。 • func_id — 指定されたライブラリ関数の返された ID 値。 関連項目 : "システム ID によるライブラリへのアクセスでの $ZF(-5) の使用" の詳細と例。 注釈 $ZF(-4, 4) から $ZF(-4, 8) については、次のセクション (“インデックス付きのコールアウト・ライブラリの使用”) を参照してください。 $ZF(-5) システム定義の ID 値によって参照されるコールアウト・ライブラリから関数を呼び出します。 retval = $ZF(-5,lib_id,func_id,args) パラメータ : • lib_id — $ZF(-4,1) によって指定されるコールアウト・ライブラリ ID 値。 • func_id — $ZF(-4,3) によって指定されるライブラリ関数 ID 値。 • args — (オプション) ライブラリ関数で必要とされる引数を含むコンマ区切りリスト。 これは、以下を返します。 • retval — ライブラリ関数の出力値、またはライブラリ関数が出力値を設定しない場合は NULL。 関連項目 : "システム ID によるライブラリへのアクセスでの $ZF(-5) の使用" の詳細と例。 8.4 インデックス付きのコールアウト・ライブラリの使用 これらの $ZF 関数を使用すると、Caché コールアウト共有ライブラリのインデックスを作成できます。これは、ロードして実 行時にその関数を呼び出すことができます。ライブラリおよびライブラリ関数は事前定義された番号で識別されます。 注釈 $ZF(-4, 1)、$ZF(-4, 2)、および $ZF(-4, 3) については、前のセクション (“インデックスなしのコールアウト・ラ イブラリの使用”) を参照してください。 $ZF(-4, 4) インデックス番号によって指定されるコールアウト・ライブラリをアンロードします。 Caché コールアウト・ゲートウェイの使用法 57 Caché コールアウトのクイック・リファレンス $ZF(-4,4,lib_index) パラメータ : • lib_index — コールアウト・ライブラリに対するユーザ指定のインデックス ($ZF(-4,5) または $ZF(-4,7) によっ て作成)。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 $ZF(-4, 5) コールアウト・システム・インデックス・テーブル内にエントリを作成します。 $ZF(-4,5,lib_index,lib_name) パラメータ : • lib_index — コールアウト・ライブラリを参照するために使用される一意のユーザ指定番号。 • lib_name — インデックスが付けられるコールアウト・ライブラリの名前。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 $ZF(-4, 6) コールアウト・システム・インデックス・テーブル内のエントリを削除します。 $ZF(-4,6,lib_index) パラメータ : • lib_index — $ZF(-4,5) への呼び出しによって前に定義されたインデックス番号。この引数は必須です (省 略可能な $ZF(-4,8) とは異なります)。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 $ZF(-4,7) コールアウト・プロセス・インデックス・テーブル内にエントリを作成します。 $ZF(-4,7,lib_index,lib_name) パラメータ : • lib_index — コールアウト・ライブラリを参照するために使用される一意のユーザ指定番号。 • lib_name — インデックスが付けられるコールアウト・ライブラリの名前。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 $ZF(-4,8) コールアウト・プロセス・インデックス・テーブル内からエントリを削除します。インデックス番号が指定されていな い場合、すべてのインデックス・エントリが削除されます。 $ZF(-4,8,lib_index) 58 Caché コールアウト・ゲートウェイの使用法 インデックス付きのコールアウト・ライブラリの使用 パラメータ : • lib_index — (オプション) $ZF(-4,7) への呼び出しによって前に定義されたインデックス番号。指定されてい ない場合、すべてのインデックス・エントリが削除されます。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 注釈 $ZF(-5) については、前のセクション (“インデックスなしのコールアウト・ライブラリの使用”) を参照してくださ い。 $ZF(-6) インデックス付きのコールアウト・ライブラリ内の関数を検索して実行します。 retval = $ZF(-6,lib_index,func_id,args) パラメータ : • lib_index — コールアウト・ライブラリに対するユーザ指定のインデックス ($ZF(-4,5) または $ZF(-4,7) によっ て作成)。 • func_id — (オプション) $ZF(-4,3) から提供された、コールアウト・ライブラリ内の関数の ID 値。これを省略し た場合は、呼び出しによって lib_index の妥当性を検証し、ライブラリをロードして、完全なライブラリ・ファイ ル名を返します。 • args — (オプション) ライブラリ関数で必要とされる引数を含むコンマ区切りリスト。 これは、以下を返します。 • retval — ライブラリ関数の出力値、またはライブラリ関数が出力値を設定しない場合は NULL。 関連項目 : “ユーザ・インデックスによるライブラリへのアクセスでの $ZF(-6) の使用” の詳細と例。 Caché コールアウト・ゲートウェイの使用法 59
© Copyright 2024 ExpyDoc