タイトルJava Watch on the X》2 - 結果的に実用的じゃないJDirectのサンプル(4)カテゴリーJava, Java Watch on the X
作成日2001/11/23 15:41:59作成者新居雅行
【MDOnline読者様限定コンテンツ】
ここで、それじゃあ、AECreateDescの実際のプログラムが存在するライブラリはどのファイルなのかということになる。実際に、こうしたシステムコールを使いたいとなると、一般にはCarbonのコールだろう。CocoaのAPIを使いたいのなら、GUIのことを無視すればいっそのことCocoa-Javaで作るのが早い。QuickTimeだったらQuickTime for Javaがある。そうなると、JDirectで使うのはCarbonのコールやあるいはコアシステムのコールということになるだろう。Carbonの場合は、サンプルにあるように、フレームワークの中にある、ライブラリのファイルを参照すればいい。システムのAPIの場合は、たいがいはCarbonのフレームワークを指定すればいいようだ。たとえば、AECreateDescは、ApplicationServicesフレームワークのAEフレームワークにあるAEDataModel.hに定義されている。だから、こちらのフレームワークのライブラリへのパス名である "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE" を、変数JDirect_MacOSXに代入してもきちんと動作する。だが、Carbonのライブラリを指定してもAECreateDescのネイティブメソッド呼び出しはきちんと動くのである。Carbonはいろんなフレームワークを統合していると思っていいかもしれない。いずれにしても、フレームワークのライブラリファイルを探し出して、そのパスを得て、JDirect_MacOSXという文字列に指定しておくのである。

なお、デバッグ機能として、JDirectによるメッセージをコンソールに表示するということができるようになっている。1つの方法は、ソース中に、

com.apple.mrj.jdirect.Linker.verbose = true;

というプログラムを入れておけばよい。これにより、ネイティブメソッドが呼び出されたときにロードされる様子や、JDirect_MacOSX変数を調べてライブラリをロードする様子を見ることができる。少なくとも、使っているライブラリが正しいかどうかといったチェックはできるだろう。ただ、GUIを使っていると、AWTがネイティブメソッドを使う段階のメッセージが大量に出てくるので、ちょっと中身が見づらくなる。なお、シェル変数の設定でも同様に、JDirectのメッセージを表示できるが、「setenv JDIRECT_VERBOSE」というコマンドを与えておけばよい。

―――注意点とハンドルやポインタの利用
ここからは個別の事情となる。まず、今回のAppleScriptを動かすプログラムを見ていただきたいが、以上のように、APIコールをネイティブメソッドで呼び出し、AEDescレコードなどをだましだまし使うという手法で、OSADoScriptを使って、AppleScriptのプログラム実行にこぎつけるまでのところはだいたい説明できているはずだ。もっとも、このnativeメソッドの定義にえらくてこずったのであるが、結果を見ればクリアなはずだ。
注意点としては、AECreateDescは、ハンドルを確保するため、その確保したメモリ領域をリリーするため、AEDisposeDescを呼び出さないといけないことだ。Javaではメモリのリリースなんてまずはしないのだが、実際に動いているのはCarbonのAPIである。だから、システムの内部的にはリリースが必要になるのだ。見てくれはJavaだけど、動きはCarbonであることは忘れてはいけない。

さらに、どうしてもハンドルやポインタを使わないといけない場面が出てくる。もちろん、そうした機能はJavaにはないが、そこでMRJでは、GenericHandleとGenericPointerというクラスを使えるようにしてある。com.apple.mrj.jdirectというパッケージに用意されている。
AppleScriptを実行した戻り値は変数resultDataに戻されるが、これはAEDescレコードである。その後半の4バイトがハンドルであるが、そのハンドルの値を直接はJavaでは使えない。そこで、new GenericHandle(ハンドルの値)で、新たにGenericHandleオブジェクトを生成する。これで、Javaのプログラムでハンドルの先のメモリブロックを管理できるようになった。GenericHandleにあるgetBytesAtメソッドは、ハンドル内の指定した位置からのデータをbyte配列として戻す。これをもとに、ハンドルにあるデータから文字列Stringを生成しているのである。

err = OSADoScript(comp, sourceData, 0, 0x54455854, 0x00000000, resultData);
if (err != 0)
OSAScriptError(comp, 0x65727273, 0x54455854, resultData);
AEDisposeDesc(sourceData);
GenericHandle dHandle = new GenericHandle(resultData[1]);
byte[] strs = dHandle.getBytesAt(0, GetHandleSize(resultData[1]));
rValue = new String(strs);

GenericHandleやGenericPointer、あるいは汎用的な構造体を利用するクラスについてのドキュメントは、Mac OS X向けにはまだ公開されていないようだが、MRJ SDKにはある。MRJ SDKのフォルダにあるMisc Documentationフォルダを見れば、そこのJavaDoc形式でドキュメントがある。それを見れば、だいたいの機能は分かるだろうし、構造体関連のクラスは、JDirectのドキュメントにも記載がある。
ただ、MRJ SDKに記載された内容のすべてがMac OS Xに適用できるものでもないのも事実だ。当面は、存在するドキュメントをうまく読みこなすということが必要になるだろう。

◇MRJ SDK 2.2
 ftp://ftp.apple.com/developer/Development_Kits/MRJ_SDK_2.2_Install.sit.bin

(この項、以上)
関連リンク