JNIにチャレンジしてみた


OpenCVについての勉強をしようと思ったんですが、OpenCVC言語向けのライブラリです。
でもC言語だとGUIをかけない私がいる。
いや、まあObjective-Cの勉強をする予定なのでそこから使うという事を考えるとXCodeを使うという手も考えられるんですけどね。
とりあえずJavaGUIを使う方法で検討してみようと思いました。
となるとやはりJNIしかない!


ということで、JNIに取りかかっていきましょう。
ここでの環境は、
MacOS X 10.5.1 Leopard
JDK 1.5.0
g++ 4.0.1
となっております。

まず、基本になるjavaファイルを書きます。

public class HelloWorldJNI {
	static {
		//ライブラリをロード
		System.loadLibrary("HelloWorldJNI");
	}
	//ネイティブメソッドを宣言
	public native String sayHelloWorld();
	
	public static void main(String[] args){
		//オブジェクトを生成
		HelloWorldJNI hello = new HelloWorldJNI();
		//メソッド呼び出し
		System.out.println(hello.sayHelloWorld());
	}
}

上の HelloWorldJNI.javaコンパイルします。

$ javac HelloWorldJNI.java

次に、外部ライブラリ(Javaが使うC言語で書いたファイル)用にヘッダファイルを生成します。

$ javah -jni HelloWorldJNI

これで HelloWorldJNI.h が生成されます。
中身はこんな感じ。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorldJNI */

#ifndef _Included_HelloWorldJNI
#define _Included_HelloWorldJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorldJNI
 * Method:    sayHelloWorld
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorldJNI_sayHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

このヘッダファイルに従ってcppファイルを作成します。
HelloWorldJNI.cppの内容。

#include "HelloWorldJNI.h"
JNIEXPORT jstring JNICALL Java_HelloWorldJNI_sayHelloWorld (JNIEnv *env, jobject obj ) {
	return env->NewStringUTF("Hello World");
}

上のファイルをコンパイルします。

$ g++ -dynamiclib -I/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Headers/ HelloWorldJNI.cpp -o libHelloWorldJNI.jnilib

libHelloWorldJNI.jnilib が生成されます。
これで準備完了。

/*
追記(2008-02-18)
注意しなければならないのが、jniライブラリ名には”lib”がついているけど、System.loadLibrary()で呼び出すときは"lib"をつけないっていうこと。先日久々にJNI使ったら、これを忘れててすごい苦労しました。
*/


最初に作った HelloWorldJNI.class を実行しましょう。

$ java HelloWorldJNI

これで Hello World が出力されたら完成だー。




さて、次はMac版のOpenCVの導入に必要な各種パッケージをインストールするのに必要なFinkの導入なんですが・・・
fink-0.27.7のインストール作業が終わって、pkg-configとかをインストールしようとしているんですが、

$ fink install pkgconfig

ってやると、

Information about 156 packages read in 2 seconds.
Use of uninitialized value in string ne at /sw/lib/perl5/Fink/Engine.pm line 1589.
Failed: no package found for specification 'pkgconfig'!

ってエラーが出るんですよね。これどうやったら解決するんだろう・・・。
誰か教えてください。
このEngine.pmを自分で直さなきゃならないんだろうか?Perlは分かんないんだよなぁ。



参考文献
InterPot生活: Mac OSX で JNI してみる逃避