シンボルテーブル2



ここですること:
 ・カスタムエディットを使って新しいシンボルを作る

  ※今回は超上級者向けです



(1)前置き

 CompileIt! 初心者、ToolBox 初心者を対象に書いていたこのシリーズの中で、今回だけちょっと特殊な章になります。
 カスタムエディットというのは CompileIt! のシンボルテーブルに精通していないと手を出せない非常にマニアックな部分です。少なくともインタネを見回したところでは、このカスタムエディットを活用したスクリプトというのにお目に掛かったことがありません。逆に言うと、これはもしかしたら私だけが持っている情報かも知れないと言うことで、今回の解説になりました。 CompileIt! をしゃぶりつくすには是非必要な情報なのですが、今のペースで行くといつになったら到達出来るか分からない(笑)ので、必要とする人(いるのか?)のために、早めに公開しておきたいということです。
 恐らく大部分の人にとっては無縁な話が続くと思います。そうでなくてもマニアなページの、これまたマニアな話題です。普通にスクリプトを書いてコンパイルする分には不要な情報ですが、ご勘弁のほどを。


(2)カスタムエディットを使う

 さて、前回までの説明でシンボルテーブルの構造が大体頭に入っていると仮定して話を進めます。まずは CompileIt! メニューから CustomEdit を選んで下さい。このシンボルエディタの詳しい使い方はマニュアルの p63 にあります(日本語版マニュアルが欲しい方はどんどん請求してね。自分で言うのもなんだけど、とても良い出来です)が、ざっと説明してみましょう。

 1)必要なヘッダファイルを入手する。
 新しいツールボックスルーチンを登録するには、そのルーチンの仕様書となるものが必要です。アップルの開発者向けサイトをぐるぐるすると、ユニバーサルヘッダなるものがありますので、拾っておきましょう。このほか新しめの技術に関しては、SDKやサンプルコードに必要なファイルが含まれることがあります。

 2)目的の関数の定義を得る
 例えば CompileIt! に無い PlotIconID という関数を登録したいとしましょう。この関数は Icons.h というヘッダファイルに含まれています。

extern pascal OSErr PlotIconID(const Rect *theRect, IconAlignmentType align, IconTransformType transform, SInt16 theResID)
THREEWORDINLINE(0x303C, 0x0500, 0xABC9);

 ".h" ファイルはC言語用のヘッダファイルなので、こんな感じになってます。ちなみに ".p" はパスカル用の定義ファイルです。もしも ".h" ファイルに目的の関数が見つからない時は ".p" ファイルも当たってみて下さい。それでもダメならSDKやサンプルコードの中のファイルを漁ります。

 3)シンボルを作る
 カスタムシンボルエディタのカードで、"New Name..." ボタンをクリックします。カード上部の "Symbol Name" フィールドに "PlotIconID" と入れて下さい。
 左に並んだラジオボタンから一番下の "$ Raw Inline Code" をチェックします。新しい ToolBox を登録する時は常にここです。
 新しく出てきたラジオボタンから一番上の "O: Command(no type)" をチェック。これは「返値なし」を意味します。 PlotIconID は ToolBox では OSErr を返す関数として定義されていますが、今回は返値を無視してコマンド扱いします。エラーを受け取りたい時は "I: 2-Byte Integer" を選べば、エラーコードを返値とする関数として登録出来ます。( OSErr は Integer です) ハンドルを返すような関数はここで "P: Pointer or Handle"、真偽値を返すタイプの関数は "B: 1-Byte Boolean" を選んでおいて下さい。
 左上の "Parameter Type List" に "R,I,I,I" と入れて下さい。これは引数のタイプを列挙したものです。第1引数 Rect は構造体なので "R" です。第2引数 IconAlignmentType はヘッダファイル中で SInt16 のことであるとあり、SInt16 は要するに short なので、Integer を表す "I" になります。同様に、第3引数の IconTransformType も 第4引数の SInt16 も "I" です。このように、CompileIt! では引数の型を R(構造体)、I(2バイト変数/short)、L(4バイト変数/long )、P(ポインタ/ハンドル)、T(4バイトOSタイプ)、S( STR255型文字列)のいづれかに当てはめて考えます。
 最後に右下の大きなフィールドに "$303C0500ABC9" と入れます。これは定義ファイルにある "0x303C, 0x0500, 0xABC9" からいらない "0x" やカンマなどを除いたものの頭に "$" を付けたものです。
 これで必要なものは全て入力しました。OKボタンを押せば、あとは普通のシンボルとして Add や Remove が出来ます。

 4)カスタムエディットの注意点
 ここまではマニュアルに書いてある通りの手順ですが、実は気を付けなければならないことがいくつかあります。ひとつはシンボルを再編集する時の注意です。一旦作ったシンボル(のみ)にマークを付けて Edit Marked... ボタンで編集し直すことが出来ますが、この時、もし編集前のシンボルが Add されたままだと、編集後のシンボルが「名前が同じで定義の違うシンボル」とみなされてしまいます。実際には編集後のシンボルを Add した時点で古い情報は無効になりますが、そのシンボルを Add する度に「重複したシンボルがあるぞ」と警告を受けるハメになります。これを避けるために、Edit Marked... ボタンを押す前に、必ず Remove ボタンを押す癖を付けておいて下さい。一旦二重定義されてしまうとその削除はとても面倒なものになります。


(3)マニュアルに無い "VAR" の扱い

 さて、ToolBox に詳しい人なら、ここまでの説明で「あれ?」と思った方がいるかも知れません。引数の指定をする時に型指定はしますが、いわゆる VAR の指定がありませんね。
 VAR というのはパスカルで使う用語で、「返値を受け取る引数」のことです。普通の引数は値を渡すだけなので値そのものを渡せば済むのですが、VAR 引数は値を受け取るために「参照渡し」が必要になります。カスタムエディットを普通に使うだけでは、この指定方法が無いのです。付け忘れたのでしょうか? それともマニュアルに書き忘れた? いづれにしろ、なんらかの方法で「この変数は参照渡ししてくれ」と指定しなければなりません。そのヒントは Tech Notes にありました。

  Tech Notes #1 にはシンボルテーブルの構造についての詳しい解説があります。これによると、シンボルテーブルのカードには隠された定義フィールドがあるのです。普段見えているシンボルリストは bg fld "Descriptions" ですが、実際の関数定義は bg fld "theSymbols" にあります。この2つのフィールドはぴったり重なっていて、普段は下になった "theSymbols" は見えません。そこでメッセージボックスから hide bg fld "Descriptions" と打ち込むと、初めて "theSymbols" フィールドが見えるようになります。なるほどね。実際の情報はここに書かれている訳だ。たった今登録したばかりの PlotIconID の定義が見えます。
  ploticonid,,PTA RIII,10,4,0,128,,,$303C0500ABC9,,0
これの読み解き方も Tech Notes に載ってますが、簡単に説明してみましょう。

 まず、この文字列を item で区切ります。 item 1 はシンボル名です。 item 3 はシンボルの属性と問題の引数指定、item 4 はシンボルの種類、item 5 はパラメータの数、そして item 7 は返値の受け取り方の指定という具合に並んでます。
 item 3 は更に word で区切ることが出来ます。 word 1 はこのシンボルの属性のようなもので、PTI は「値を返さない ToolBox ルーチン」という意味です。 word 2 には先ほど入力した引数のタイプが並んでいます。「日本語マニュアル」には Tech Notes の日本語版も含まれていますので、是非入手して参照して下さい。

 さて問題の VAR指定の方法ですが、この文字列の item 3 に word 3 を付け足します。 GraphicsImporter の GetGraphicsImporterForFile ルーチンを使って実際の作業をしてみましょう。


(4)"VAR" 引数の登録

 GraphicsImporter のシンボルをひとつ登録します。シンボル登録の練習用なので、実際の使い方には触れません。 VAR引数の指定方法だけを説明します。

 まず ImageCompresson.p から GetGraphicsImporterForFile の定義を探し出します。

FUNCTION GetGraphicsImporterForFile({CONST}VAR theFile: FSSpec; VAR gi: ComponentInstance): OSErr;
{$IFC NOT GENERATINGCFM}
INLINE $203C, $0008, $006E, $AAA3;
{$ENDC}

 パスカル用のファイルなので書式が違いますが、要点は読みとれると思います。余りに名前が長いので "GraphicsImporter" の部分は "GI" と略して、"GetGIForFile" として登録します。普通のシンボルと同じようにカスタムエディットで登録して下さい。タイプは "O: Command(no type)" でいいでしょう。エラーは別の方法で調べられます。引数のリストは "R,P"、コードは "$203C0008006EAAA3" を入力します。OKボタンを押して一旦入力を終えます。

 ここから VAR の指定です。この関数は第2引数に GraphicsImporter が返って来るので、第2引数が VAR 引数となります。第1引数にある CONST は「この変数は関数内でいじるな」という指定です。また第1引数にも VAR という指定が見えますが、これはパスカルで構造体を渡すときの流儀です。 CompileIt! では構造体は無条件で参照渡しの扱いになるので、わざわざ VAR 指定する必要はありません。(しても意味がない) 今回は第2引数だけ VAR 引数として指定してみます。

 まず、カスタムシンボルカード上でメッセージボックスに hide bg fld "Descriptions" を打ち込んで、bg fld "theSymbols" が見える状態にします。次にフィールドをダブルクリックしてフィールドのロックを外します。これで編集自由になりました。
  getgiforfile,,PTA RP,10,2,0,128,,,$203C0008006EAAA3,,0
となっている定義文字列のうち、item 3 の "PTA RP" のうしろに半角スペースひとつと "AV" を入れます。するとこのようになります。
  getgiforfile,,PTA RP AV,10,2,0,128,,,$203C0008006EAAA3,,0
実際にはフィールド上で折り返し処理が行われるのでちょっと見辛くなりますが、注意深く作業して下さい。この item 3 の word 3 が引数の VAR 指定です。 A は通常の引数、V が VAR 引数。これを引数の数だけ並べます。例えば引数が4つあり、そのうち4番目の引数だけが VAR 引数だった場合は、この item 3 の word 3 は "AAAV" となります。

 私はちょくちょく定義をいじるので、これら一連の作業が簡単になるよう、カスタムエディタカードに専用のボタンをくっつけてます。このへんがスタックである CompileIt! の強みですね。
 注意したいのは、定義をいじると「違うシンボル」になることです。カスタムエディットの注意にも書きましたが、定義をいじる前には必ず "Remove" して下さい。そうしないと、「二重定義だ」とうるさいダイアログが出ることになります。


inserted by FC2 system
Next



CompileIt! Lab.

UDI's HomePage