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) |