jni1.c

最終更新:2009/10/24

jni1.c

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: }
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)