/* * jni1.c * C から JNI で Java クラスを実行するサンプル * 引数で指定された Java クラスの static void main (String[] args) を実行 * * ポイント: * String[] の作り方と static な void 型メソッドの実行方法 * * 注意: * jvm.dll へのパスを環境変数 PATH に入れる。 * 例: * PATH C:\Program Files\Java\jre6\bin\client;%PATH% */ #define USAGE "Usage: jni1 ..." #include "jni.h" #define METHOD_NAME "main" #define METHOD_SIGNATURE "([Ljava/lang/String;)V" /* * シグネチャは javap -s で調べることができる。 * javap 実行例: % javap -s Foo Compiled from "Foo.java" public class Foo extends java.lang.Object{ public Foo(); Signature: ()V public static void main(java.lang.String[]); Signature: ([Ljava/lang/String;)V } */ int main(int argc, char* argv[]) { int error_flag = 0; JNIEnv *jniEnv; JavaVM *jvm; JavaVMInitArgs jvmArgs; jclass jcTarget; jmethodID jmMain; jthrowable throwResult; jclass jcString; jobjectArray jmMainArgs; JavaVMOption jvmOptions[1]; if (argc < 2) { fprintf(stderr,"%s\n", USAGE); /* * argv[0]:このプログラムの名前 * argv[1]:クラスの名前 * argv[2]以降:argv[1] で指定したクラスの main メソッドに渡す引数 */ return 1; /* 異常終了 */ } /* クラスパスにカレントディレクトリを指定。 */ jvmOptions[0].optionString = "-Djava.class.path=."; jvmArgs.version = JNI_VERSION_1_2; jvmArgs.options = jvmOptions; jvmArgs.nOptions = 1; jvmArgs.ignoreUnrecognized = JNI_TRUE; /* JavaVM の作成 */ { int result = JNI_CreateJavaVM(&jvm, (void **)&jniEnv, &jvmArgs); if (result != 0) { fprintf(stderr, "ERROR: JNI_CreateJavaVM(%d).\n", result); return 1; /* 異常終了 */ } } /* 第一引数で指定されたクラスの検索 */ jcTarget = (*jniEnv)->FindClass(jniEnv, argv[1]); if (jcTarget == 0) { fprintf(stderr, "ERROR: FindClass: %s\n", argv[1]); error_flag = 1; goto K_FINALLY_; } /* メソッド取得 */ jmMain = (*jniEnv)->GetStaticMethodID(jniEnv, jcTarget, METHOD_NAME, METHOD_SIGNATURE); if (jmMain == 0) { fprintf(stderr, "ERROR: GetStaticMEthodID %s %s\n", METHOD_NAME, METHOD_SIGNATURE); error_flag = 1; goto K_FINALLY_; } /* String クラスの検索 */ jcString = (*jniEnv)->FindClass(jniEnv, "Ljava/lang/String;"); if (! jcString) { fprintf(stderr, "ERROR: FindClass Ljava/lang/String;\n"); error_flag = 1; goto K_FINALLY_; } /* main メソッドに渡す配列(String[])の用意。 * 配列の要素数==argc-2 */ jmMainArgs = (*jniEnv)->NewObjectArray(jniEnv, argc-2, jcString, NULL); if (! jmMainArgs) { fprintf(stderr, "ERROR: NewObjectArray %d Ljava/lang/String;\n", argc-2); error_flag = 1; goto K_FINALLY_; } /* main メソッドに渡す配列(String[])に値を設定。argv[2] 以降を設定。 * jmMainArgs[0] ← argv[2] * jmMainArgs[1] ← argv[3] * … */ { int i=0; for (i=0; iSetObjectArrayElement(jniEnv, jmMainArgs, (jsize)i, (*jniEnv)->NewStringUTF(jniEnv, argv[i +2 ])); } } /* main メソッド呼出 */ (*jniEnv)->CallStaticVoidMethod(jniEnv, jcTarget, jmMain, jmMainArgs); throwResult = (*jniEnv)->ExceptionOccurred(jniEnv); if (throwResult != NULL) { fprintf(stderr,"ExceptionOccurred\n"); (*jniEnv)->ExceptionDescribe(jniEnv); (*jniEnv)->ExceptionClear(jniEnv); error_flag = 1; goto K_FINALLY_; } K_FINALLY_: (*jvm)->DestroyJavaVM(jvm); if (error_flag) { /* 異常終了 */ return 1; } /* 正常終了 */ return 0; }