jni1.c
最終更新:2009/10/24
001: /* 002: * jni1.c 003: * C から JNI で Java クラスを実行するサンプル 004: * 引数で指定された Java クラスの static void main (String[] args) を実行 005: * 006: * ポイント: 007: * String[] の作り方と static な void 型メソッドの実行方法 008: * 009: * 注意: 010: * jvm.dll へのパスを環境変数 PATH に入れる。 011: * 例: 012: * PATH C:\Program Files\Java\jre6\bin\client;%PATH% 013: */ 014: 015: #define USAGE "Usage: jni1 <java_class_name> <arg0> <arg1>..." 016: 017: #include "jni.h" 018: 019: #define METHOD_NAME "main" 020: #define METHOD_SIGNATURE "([Ljava/lang/String;)V" 021: 022: /* 023: * シグネチャは javap -s <java_class_name> で調べることができる。 024: * javap 実行例: 025: 026: % javap -s Foo 027: Compiled from "Foo.java" 028: public class Foo extends java.lang.Object{ 029: public Foo(); 030: Signature: ()V 031: public static void main(java.lang.String[]); 032: Signature: ([Ljava/lang/String;)V 033: } 034: 035: */ 036: 037: int main(int argc, char* argv[]) 038: { 039: int error_flag = 0; 040: 041: JNIEnv *jniEnv; 042: JavaVM *jvm; 043: JavaVMInitArgs jvmArgs; 044: 045: jclass jcTarget; 046: jmethodID jmMain; 047: 048: jthrowable throwResult; 049: jclass jcString; 050: jobjectArray jmMainArgs; 051: JavaVMOption jvmOptions[1]; 052: 053: if (argc < 2) { 054: fprintf(stderr,"%s\n", USAGE); 055: /* 056: * argv[0]:このプログラムの名前 057: * argv[1]:クラスの名前 058: * argv[2]以降:argv[1] で指定したクラスの main メソッドに渡す引数 059: */ 060: return 1; /* 異常終了 */ 061: } 062: 063: /* クラスパスにカレントディレクトリを指定。 */ 064: jvmOptions[0].optionString = "-Djava.class.path=."; 065: jvmArgs.version = JNI_VERSION_1_2; 066: jvmArgs.options = jvmOptions; 067: jvmArgs.nOptions = 1; 068: jvmArgs.ignoreUnrecognized = JNI_TRUE; 069: 070: /* JavaVM の作成 */ 071: { 072: int result = JNI_CreateJavaVM(&jvm, (void **)&jniEnv, &jvmArgs); 073: if (result != 0) { 074: fprintf(stderr, "ERROR: JNI_CreateJavaVM(%d).\n", result); 075: return 1; /* 異常終了 */ 076: } 077: } 078: 079: /* 第一引数で指定されたクラスの検索 */ 080: jcTarget = (*jniEnv)->FindClass(jniEnv, argv[1]); 081: if (jcTarget == 0) { 082: fprintf(stderr, "ERROR: FindClass: %s\n", argv[1]); 083: error_flag = 1; 084: goto K_FINALLY_; 085: } 086: 087: /* メソッド取得 */ 088: jmMain = (*jniEnv)->GetStaticMethodID(jniEnv, jcTarget, 089: METHOD_NAME, METHOD_SIGNATURE); 090: if (jmMain == 0) { 091: fprintf(stderr, "ERROR: GetStaticMEthodID %s %s\n", 092: METHOD_NAME, METHOD_SIGNATURE); 093: error_flag = 1; 094: goto K_FINALLY_; 095: } 096: 097: /* String クラスの検索 */ 098: jcString = (*jniEnv)->FindClass(jniEnv, "Ljava/lang/String;"); 099: if (! jcString) { 100: fprintf(stderr, "ERROR: FindClass Ljava/lang/String;\n"); 101: error_flag = 1; 102: goto K_FINALLY_; 103: } 104: 105: /* main メソッドに渡す配列(String[])の用意。 106: * 配列の要素数==argc-2 107: */ 108: jmMainArgs = (*jniEnv)->NewObjectArray(jniEnv, argc-2, jcString, NULL); 109: if (! jmMainArgs) { 110: fprintf(stderr, 111: "ERROR: NewObjectArray %d Ljava/lang/String;\n", argc-2); 112: error_flag = 1; 113: goto K_FINALLY_; 114: } 115: 116: /* main メソッドに渡す配列(String[])に値を設定。argv[2] 以降を設定。 117: * jmMainArgs[0] ← argv[2] 118: * jmMainArgs[1] ← argv[3] 119: * … 120: */ 121: { 122: int i=0; 123: for (i=0; i<argc-2; i++) { 124: (*jniEnv)->SetObjectArrayElement(jniEnv, jmMainArgs, (jsize)i, 125: (*jniEnv)->NewStringUTF(jniEnv, argv[i +2 ])); 126: } 127: } 128: 129: /* main メソッド呼出 */ 130: (*jniEnv)->CallStaticVoidMethod(jniEnv, jcTarget, jmMain, jmMainArgs); 131: 132: throwResult = (*jniEnv)->ExceptionOccurred(jniEnv); 133: if (throwResult != NULL) { 134: fprintf(stderr,"ExceptionOccurred\n"); 135: (*jniEnv)->ExceptionDescribe(jniEnv); 136: (*jniEnv)->ExceptionClear(jniEnv); 137: error_flag = 1; 138: goto K_FINALLY_; 139: } 140: 141: K_FINALLY_: 142: 143: (*jvm)->DestroyJavaVM(jvm); 144: 145: if (error_flag) { 146: /* 異常終了 */ 147: return 1; 148: } 149: 150: /* 正常終了 */ 151: return 0; 152: }
KAKU PROJECT (2009) |