top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
シンプルな C言語からJava言語を呼び出すJNIサンプルを作成しました。
シンプルな C言語からJava言語を呼び出すJNIサンプル・トイプログラムを作成しました。
C言語を久しぶりに触ったのですが、もはや かなり忘れてしまっていることが判明しました。 C言語ソースコード
/*
* シンプルなJNIサンプル。
*/
#include "stdafx.h"
#include "jni.h"
int main(int argc, char* argv[])
{
JNIEnv *jnienv;
JavaVM *javavm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = true;
printf("JavaVMを作成.\n");
int result = JNI_CreateJavaVM(&javavm, (void **)&jnienv, &vm_args);
if (result != 0) {
printf("JavaVMの作成に失敗しました(%d).\n", result);
return 1;
}
printf("クラス検索.\n");
jclass cls = jnienv->FindClass("MyClass");
if (cls == 0) {
printf("クラス検索に失敗しました.\n");
return 1;
}
printf("メソッド取得.\n");
jmethodID mid = jnienv->GetStaticMethodID(cls, "process", "()Ljava/lang/String;");
if (mid == 0) {
printf("メソッド取得に失敗しました.\n");
return 1;
}
printf("メソッド呼出.\n");
jobject objResult = jnienv->CallStaticObjectMethod(cls, mid);
jthrowable throwResult = jnienv->ExceptionOccurred();
if (throwResult != NULL) {
printf("例外が発生しました.\n");
jnienv->ExceptionDescribe();
jnienv->ExceptionClear();
return 1;
}
if (objResult == NULL) {
printf("メソッドの戻り値がnullでした.\n");
} else {
jstring strResult = (jstring) objResult;
printf("[%s]\n", jnienv->GetStringUTFChars(strResult, NULL));
}
printf("JavaVMを破棄.\n");
result = javavm->DestroyJavaVM();
if (result != 0) {
printf("JavaVMの破棄に失敗しました(%d).\n", result);
return 1;
}
return 0;
}
jvm.dllにあらかじめパスを通しておく必要があります。職業プログラミングの世界では、もっと賢い実装をおこなうでしょう。でも、そうすると行数が増えるので今回のトイプログラムの主旨とは異なるため実装を割愛しました。
JNIにまつわる異常系は、ひととおりおりこんで実装したつもりです。Java側の例外がC言語側で捕捉できることは確認しました。
GetStaticMethodID の第3引数は *.classファイルのなかから文字列を複写して活用するのが簡単で確実な方法です。これを一から手で書き起こすのは、かなり難しいです。
この例では、アタッチ・デタッチ関連のAPIを呼んでいません。
文字列の受け渡しまわりについて、実装が割愛されています。もっと賢い実装があるはずです。加えて、文字列のメモリ解放など留意点があるはずですが、これも割愛しています。
呼び出される Javaのサンプルは下記のようなものになります。 MyClass.java
public class MyClass {
public static String process() {
return "Hello world.";
}
}
関連する日記
blancoMessageのPHPソースコード生成機能ですが、最低限の単体試験をパスする状態にまで進みました。
自動生成されるソースコード