| ログイン | ご入会 |
ADC連絡先
|
|
|
スクリプティング機能追加とは何か?スクリプティング機能追加はAppleScript言語の構文を拡張するメカニズムを提供します。スクリプティング機能追加はAppleイベントを処理するものと、Appleイベントデータのcoercionを行うものに分類できます。Appleイベントを処理するタイプのスクリプティング機能追加は、アプリケーションで使われているAppleイベントハンドラと同じ要領で実装しますが、スクリプティング機能追加は特殊な実行環境におかれているので、Appleイベントハンドラや環境変数を正しく扱うためには、更に次のルーチンを実装しなければなりません。
スクリプティング機能追加によってインストールされるAppleイベントハンドラとAppleイベントデータcoercionハンドラは、一般的にアプリケーションで使われるハンドラと同じ方法で実装します。スクリプティング機能追加とアプリケーションの違いは、コードのパッケージされている方法と、実行方法です。これから、スクリプティング機能追加のパッケージと実行方法について詳しく説明します。 スクリプティング機能追加のパッケージ化スクリプティング機能追加は2通りのパッケージが存在します。
スクリプティング機能追加の初期化スクリプティング機能追加の初期化ルーチンでは、必要なハンドラのインストール、メモリの確保、その他の準備処理を行います。初期化ルーチンは以下のように構成します。
スクリプティング機能追加の初期化ルーチンはパッケージ方法によって、実装方法が異なります。CFM形式の場合、Code Fragmentの初期化ルーチンが使用されます。一方、Mach-O形式の場合、“SAInitialize”と言うルーチンを定義して、エキスポートしなければなりません。 CFM形式のスクリプティング機能追加の場合は、Code Fragmentの初期化ルーチンが呼ばれます。スクリプティング機能追加は、初期化ルーチン以外のところで自分のリソースフォークを開くことがあれば、初期化ルーチン内で取得したリソースファイルへの参照をグローバル変数などに保存します。リスト2はCFM形式のスクリプティング機能追加の初期化ルーチンの例です。
スクリプティング機能追加の初期化ルーチンに渡されるinitBlkPtrパラメータは、スクリプティング機能追加のリソースファイルを参照するための情報が含まれています。初期化ルーチン以外のハンドラで自分のリソースフォークを開く場合は、参照情報をグローバル変数などに保存しておきます。リスト3ではエイリアスをグローバル変数に保存しています。
Mach-O形式のスクリプティング機能追加は“SAInitialize”と言う関数をエキスポートしなければなりません。この関数はスクリプティング機能追加初期化時に呼ばれます。リスト4ではMach-Oの初期化関数の一例を示します。
SAInitializeのadditionBundleパラメータはスクリプティング機能追加のバンドルを指します。この値を使って、バンドル内のリソースにアクセスすることができます。この値をグローバル変数などに保存すれば、初期化時以外のハンドラでバンドル内のリソースにアクセスすることができます。additionBundleはスクリプティング機能追加がロードされている間有効ですので、CFRetainを呼び出す必要はありません。 CFM形式のスクリプティング機能追加の場合、Code Fragmentの初期化ルーチンの名前を指定する方法は開発環境に依存しますので、開発環境の説明書をお読み下さい。Code Fragment Manager、CFMの初期化ルーチン、Mach-Oについてはこの後の参考文献をご覧下さい。 スクリプティング機能追加の終了終了ルーチンでは、スクリプティング機能追加を終了させるために必要な処理を行います。特に、次の処理を欠かさずに行う必要があります。
スクリプティング機能追加の終了ルーチンは、AppleScriptがスクリプティング機能追加との接続をクローズするときに呼び出されます。このような接続のクローズは、スクリプティング機能追加がスクリプティング機能追加フォルダから外された後、AppleScriptが次に初期化されたタイミングです。 スクリプティング機能追加のロードやアンロードは“gdut”イベントが受理されたタイミングで行われます。AppleScriptはコンポーネントへの接続が開いた後、スクリプトをコンパイルする前にロードやアンロードを行います。ただし、システム終了時にアンロードは行われないので、終了ルーチンが実際に呼ばれるのは、スクリプティング機能追加がスクリプティング機能追加フォルダから外された後に、最初に“gdut”イベントが到達した時のみです。これはMac OS 9やMac OS Xも共通していますが、Mac OS Xの場合、スクリプティング機能追加はプロセスごとにアンロードされます。(スクリプティング機能追加を取り除いたあとは、その機能追加がロードされていたすべてのプロセスに対して“gdut”イベントを送信しないと、完全に除去できないことになります。Mac OS 9の場合は、どれか1つアプリケーションに対して“gdut”イベントを送信するだけで、完全に除去できました。)リスト5は、スクリプティング機能追加の終了ルーチンの一例です。スクリプティング機能追加がCFM形式のバイナリとして提供されている場合は、CFMの終了ルーチンをスクリプティング機能追加の終了ルーチンに設定しなければなりません。スクリプティング機能追加がMach-O形式のバイナリとして提供されている場合、AppleScriptはスクリプティング機能追加をアンロードする直前にSATerminateを呼びます。
CFM形式のスクリプティング機能追加の場合、終了ルーチンの設定方法は開発環境によって異なりますので、詳しくは開発環境の説明書をご覧下さい。CFMコードフラグメント、CFM初期化ルーチン、バンドル、Mach-O形式等の概念的な説明については、参考文献もご覧下さい。 リファレンスカウントAppleScriptがスクリプティング機能追加をアンロードする際、まずスクリプティング機能追加が使用中かどうかを確認します。使用中の場合はアンロードすることができないので、アンロードは取り消されるか、使用状況に変化があるまで待ち状態になります。 AppleScriptは2つの方法で、スクリプティング機能追加の使用状況を確認します。CFM形式のスクリプティング機能追加はgAdditionReferenceCountと言うグローバル変数をエキスポートします。Mach-O形式のスクリプティング機能追加はSAIsBusyと言うルーチンをエキスポートします。CFM形式で使われているスクリプティング機能追加のgAdditionReferenceCount変数は、リスト6のSAIsBusyルーチンの結果と同じように扱われます。要約すると、gAdditionReferenceCountがゼロ以外の場合、そのスクリプティング機能追加は使用中の見なされ、アンロードされることはありません。
すべてのAppleイベントハンドラとAppleイベントデータcoercionハンドラでは、実行時にgAdditionReferenceCountを1つ増やし、終了直前に1つ減らします。リスト7は典型的なハンドラルーチンの実装例です。
その他Mac OS Xの実行環境Mac OS Xの実行環境の場合、スクリプティング機能追加はAppleScriptに接続するアプリケーションが起動する度に、そのアプリケーションのアドレス空間にロードされます。このように、一つのスクリプティング機能追加が一度に複数ロードされることもあるので、プリンタやシリアルポートなどのシステムリソースを使用する場合はスクリプティング機能追加間で共有することも想定しなければなりません。 スクリプティング機能追加バンドルリソースの取得方法Mach-Oバンドル形式で提供されているスクリプティング機能追加は、バンドル内のリソースやファイルにアクセスすることがあります。この場合は、SAInitializeで受け取ったCFBundleRefを保存して、ハンドラ内で利用します。
スクリプティング機能追加では、受け取ったバンドルリファレンスに対してCFRetainを呼ぶ必要はありません。受け取ったバンドルリファレンスはスクリプティング機能拡張が開いている限り(SATerminateが呼ばれるまで)有効です。 スクリプティング機能追加のバンドル内の個々のリソースへのアクセス方法についてはこの後の参考文献をご覧下さい。 スクリプティング機能追加リソースファイルの取得方法単一のCFMファイルとして提供されているスクリプティング機能追加は、ハンドラ実行中にリソースフォークへのアクセスが必要となることが多々あります。初期化ルーチン実行時にファイルのFSSpecを保存することで、後程リソースが必要となった時点でリソースフォークを開いてデータをロードすることができます。 Code Fragment Managerが初期化ルーチンを呼び出す際は、初期化ルーチンに渡されるCFragInitBlock内にFSSpecへのポインタを予め設定しています。スクリプティング機能追加では、このポインタをグローバル変数に保存しておくと便利です。
スクリプティング機能追加がハンドラ内で開いたリソースファイルは、ハンドラ終了時までにクローズしなければなりません。また、ハンドラ内でリソースファイルを開く場合、リソースチェーンを変更しないような工夫が必要です。以下の例では、ハンドラ内でリソースファイルを開き、リソースチェーンの状態を保存しています。
ローカルシステムとリモートシステムからのイベントリモートシステムからのイベントを検出して拒否するかどうかはそれぞれのスクリプティング機能追加ハンドラが決定します。ハンドラは、受信したイベントに含まれるkeyEventSourceAttr属性をチェックして、そのイベントのソースを判断できます。リモートシステムからのイベントは、kAERemoteProcessという属性値を持ちます。
参考文献
|