[index]

Poor Man's Java for Macintosh: JNI する


環境

  1. MRJ SDK 2.1.4 / MRJ SDK 2.2 Early Access 2
  2. MPW-PR (with MPW Shell 3.5f7, MrC 4.1, etc)

MRJ SDK 内の MPW Tools は、必要があれば "{MPW}User Commands" にコピーしておく。

最初にやること

  1. ほんとに JNI を使わなければならないのか、よくよく考える。
  2. 使うと決めたら、どのメソッドを対象とするかを決める。
  3. 共有ライブラリ名を決める。

手順

  1. java ソースを書く。
    1. 共有ライブラリをロードすること。
    2. native 指定したしかるべきメソッドを含むこと。
  2. java class を生成する。
  3. C のヘッダを生成する。
  4. C のソースを書く。
  5. 共有ライブラリとして make する。
  6. 共有ライブラリを適切な位置に配置し、動かす。

(MPW 上で java るならば) MPW Tools 内の java tools

classpath を設定しておく。

Set -e classpath ':,HD:system:extentions:MRJ Libraries:MRJClasses:JDKClasses.zip,
HD:system:extentions:MRJ Libraries:MRJClasses:MRJClasses.zip,
HD:system:extentions:MRJ Libraries:MRJClasses'

など。 上記を記述した script ファイルを "{MPW}Startup Items" に入れておく。

Java ソースを書く。

こんな感じ。
    public class Hogehoge {
        static {
            try {
                System.loadLibrary("hogeLib");
            }
            catch (UnsatisfiedLinkError e) {
                System.err.println("can't load library.");
            }
        }
        public native String nativeMethod();
    }

Java ソースをコンパイルして class ファイルを得る。

Roaster からなら Project メニューから make (command + m) を選ぶだけ。MPW ツールは JDK と同じなので javac で佳い。

javah で C のヘッダを生成する。

MPW Tools 内の java tools

パッケージ名がディレクトリ名にマップされるので、開始位置に注意。パッケージ相対ディレクトリのトップに居なければならない。

MRJ SDK/Tools/JDK Tools/javah

パッケージ名がディレクトリ名にマップされるので、開始位置に注意。パッケージ相対ディレクトリのトップに居なければならない。 パッケージ相対ディレクトリの上からフォルダごとドロップして、classpath フィールドをエディットすれば佳い。 JNI-Style Prototypes は disable になっているが、常に on 状態 (-jni) なんだそうな。 help ボタンを押してみるべし。

例: jni_sample_JNITest.h

C ソースを書く。

export 指定が必要。リンク時に指定する方法もあるが、 #pragma の方が簡単。 javah が生成したヘッダのインクルードを忘れずに。

こんな感じ。
    #pragma export on
    #include "header produced by javah."
    #include <stdio.h>
    #include <stdlib.h>

    #define MY_JNI_VERSION  ("1.0 build 1")

    JNIEXPORT jstring JNICALL Java_jni_sample_JNITest_getVersion
      (JNIEnv *env, jobject jobj)
    {
        return (*env)->NewStringUTF(env, MY_JNI_VERSION);
    }
    (後略)

MPW での Create Build Commands...

Create Build Commands...
  1. プログラム名は「ライブラリ名 + 拡張子」を指定する。
  2. ソース指定を指定する。
  3. プログラム・タイプは、当然、共有ライブラリを指定する。
  4. include path 指定に jni 関係のヘッダ・パスを追加する。 jni.hMRJ SDK/Interfaces&Libraries/CIncludes にある。 MPW の include path にコピーしても使えるが、その場合は jni_md.h も忘れないように。
  5. 生成するライブラリのファイル名は java のソースでの System.loadLibrary() に渡すライブラリ名と合致していなければならない。 (拡張子を除く)
CreateMake Options.
Other Options.

これを走らせると、 make ファイル「プログラム名 + .make」が得られる

make ファイルを修正する。

これで make 一発で共有ライブラリができれば文句ないのだが、もう一箇所手を加えないといけない。 リンク・オプションとして -fragname {LibraryName} が必要。 ライブラリ名も java のソースでの System.loadLibrary() に渡すライブラリ名と合致していなければならない。 リンク・オプションで指定を追加する。

    (前略)
    LibraryName  = "hogeLib"
    (中略)
    myJNITest.shlib  {MondoBuild} {ObjectsPPC}
        PPCLink 
            -fragname {LibraryName}  (実質追加するのはここだけ)
            -o {Targ} {SymPPC} 
    (後略)
(「カ」に見えるのは option + d, 「ト」に見えるのは option + f)

例: myJNITest.shlib.make

共有ライブラリ・ファイルを生成する。

Nuild メニューから Build... / Full Build... を指定。セッションの最初の一回だけプログラム名を尋ねてくるので答えてやる。

共有ライブラリの位置は?

  1. アプリケーションが抱える。
  2. アプリケーションと同じ位置。 (JBindery で java アプリケーションを生成しなければ、この場合の「アプリケーション」は JBindery を意味するので注意)
  3. extentions フォルダ。
  4. extentions/MRJ Libraries フォルダ。 (ここのサブ・ディレクトリはスキャンされない。extentions/MRJ Libraries/MRJClasses はダメ)

Roaster の Project メニュー から Run with Apple MRJ (cmd + r) で走らせると、カレント・ディレクトリに JBindery document (Crtt: jint, Type: jrun) ができる。これを一度 JBindery にドロップインしてアプリケーションにしておく。んで、共有ライブラリもここに置いておけばよい。一度アプリケーション化していても、再度 JBindery にドロップインすれば、各種設定を変更できる。

余録

デバッグ目的で printf が使える。MPW で作った shlb 内で標準出力に書き出すと、ファイルにリダイレクトしてくれるのである。ありがたや。 MPW で Squeak を作ってみれば判るように、アプリケーションでも、標準出力に書き出すとファイルにリダイレクトしてくれるのである。


Created: Jan, 2000.
[index]