タイトル
TOPJavaJNI → This Page

JNI サンプル(戻り値に文字列の配列を返すJNIサンプル)

前置き

ここではJavaJNI(Java Native Interface)のサンプルを紹介します。

サンプル概要

Java から 戻り値に文字列の配列を返す C の関数を呼び出すサンプルです。
引数に数字を渡すと、その数だけ配列に文字列をセットして返します。


SampleJava7.java

呼び出す側(Java)として以下のファイルを作成します。
public class SampleJava7 {
	// ライブラリをロード
	static {System.loadLibrary("SampleC7");}
	
	// ネイティブメソッドを宣言
	native String[] getStrings(int num);
	
	public static void main(String[] args) {
		SampleJava7 main = new SampleJava7();
		
		int num = 5;
		String[] ret = main.getStrings(num);
		for (int i = 0; i < num; i++) {
			System.out.println(ret[i]);
		}
	}
}

コマンドプロンプトを開き、以下のコマンドでコンパイルします。
(パスは SampleJava7.java を作成したフォルダにして下さい)
javac SampleJava7.java

SampleJava7.h

コマンドプロンプトを開き、以下のコマンドでヘッダファイルを出力します。
(パスは SampleJava7.java を作成したフォルダにして下さい)
javah -jni SampleJava7

すると以下の内容のファイルが作成されます。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class SampleJava7 */

#ifndef _Included_SampleJava7
#define _Included_SampleJava7
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     SampleJava7
 * Method:    getStrings
 * Signature: (I)[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL Java_SampleJava7_getStrings
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

SampleC7.cpp

呼び出される側(C)として以下のファイルを作成します。
先ほど Java を作成したフォルダと同じフォルダに作成して下さい。
#include <windows.h>
#include "SampleJava7.h"
JNIEXPORT jobjectArray JNICALL Java_SampleJava7_getStrings
(JNIEnv *env, jobject obj, jint num) {
	int count = num;
	
	// 配列文字列を作成
	jclass c = env->FindClass("java/lang/String");
	jobjectArray ret = env->NewObjectArray(count, c, jstring());
	
	int i;
	for (i = 0; i < count; i++) {
		const char *pBuff = "あいうえお";
		int len = strlen(pBuff);
		
		// Unicode文字列の長さを取得
		int uniLen = MultiByteToWideChar(CP_ACP, 0, pBuff, len, NULL, 0);
		
		WCHAR *retBuff = new WCHAR[uniLen];
		
		// Unicode文字列に変換
		MultiByteToWideChar(CP_ACP, 0, pBuff, len, retBuff, uniLen);
		
		// Javaの文字列生成
		jstring jstr = env->NewString((jchar *)retBuff , uniLen);
		
		delete retBuff;
		
		// 配列の指定インデックスに文字列をセット
		env->SetObjectArrayElement(ret, i, jstr);
	}
	
	/*
	// 日本語(全角文字)を使わないのであれば以下だけで対応可能
	int i;
	for (i = 0; i < count; i++) {
		char* src = "abcde";
		jstring jstr = env->NewStringUTF(src);
		
		// 作成した配列文字列に文字列をセット
		env->SetObjectArrayElement(ret, i, jstr);
	}
	*/
	
	return ret;
}

コマンドプロンプトを開き、以下のコマンドでコンパイルします。
(パスは SampleJava7.java を作成したフォルダにして下さい)
bcc32 -IC:\j2sdk1.4.2_08\include -IC:\j2sdk1.4.2_08\include\win32 -tWD SampleC7.cpp

(注意)
上記の C:\j2sdk1.4.2_08 部分は各自のマシンの JDK のパスにあわせて下さい。

警告は出るかもしれませんが、エラーが出なくて DLL が作成されればコンパイル成功です。


コンパイルのパスについての注意点
JDK のパスに半角スペースなどが含まれている場合は、パスをダブルクォートで囲む必要があります。
bcc32 -I"C:\Program Files\Java\j2sdk1.4.2_08\include" -I"C:\Program Files\Java\j2sdk1.4.2_08\include\win32" -tWD SampleC7.cpp


サンプルの実行

コマンドプロンプトを開き、以下のコマンドで実行します。
(パスは SampleJava7.java を作成したフォルダにして下さい)
java SampleJava7

あいうえお
あいうえお
あいうえお
あいうえお
あいうえお
と表示されれば成功です。

サンプルのダウンロード

サンプルのダウンロード


更新履歴

2008/04/01 コンパイル時のパスについて注意点追加
2007/12/01 Javaのコーナー細分化に伴い、URL の変更


TOPJavaJNI → This Page