{{category プログラミング}} {{category Java}} {{category C言語}} /opt/blackdown-jdk-1.4.2以下にJavaがインストールしてある場合です. linuxおよび,linuxエミュレータを導入しているFreeBSDでも実行できることを確認しました.ただし,この場合は,linux版のgccでコンパイルすることが必要です. !サンプルコード 以下のTest.javaを呼びだすC言語のコードを書くことにする. public class Test{ public static void testmethod(){ System.out.println("succeseed of calling."); } public int sumation(int a, int b){ return a+b; } } !C言語側のコード #include #include #include int main(int argc, char **argv) { JNIEnv *env; JavaVM *jvm; JNIEnv jni; JavaVM vmi; JavaVMInitArgs vm_args; JavaVMOption options[4]; printf("beginning execution...?n"); /* * /opt/blackdown-jdk-1.4.2/がJavaのルートディレクトリの場合 */ options[0].optionString = (char *) ? "-Djava.class.path=.:/opt/blackdown-jdk-1.4.2/jre/lib/rt.jar"; options[1].optionString = (char *) "-Djava.compiler=NONE"; vm_args.version = JNI_VERSION_1_4; vm_args.options = options; vm_args.nOptions = 2; vm_args.ignoreUnrecognized = JNI_FALSE; /* * JavaVMを初期化,起動する * JNIインターフェースへのポインタを返す */ JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args); jni = *env; vmi = *jvm; /* * クラスをさがす */ jclass cls = jni->FindClass(env, "Test"); if (cls == 0) { printf("cannot found Test?n"); exit(1); } /* * Methodをさがす * GetStaticMethodIDの引数については後述 */ jmethodID mid = jni->GetStaticMethodID(env, cls, "testmethod", "()V"); if (mid == 0) { printf("Could not locate method testmthod with signature ()V"); exit(1); } /* * 実行 */ jni->CallStaticVoidMethod(env, cls, mid, NULL); /* * VMを終了する */ vmi->DestroyJavaVM(jvm); } !コンパイルの仕方 ...gccでインクルードパスを複数指定するときのデリミタってなかったっけ? % gcc -I/opt/blackdown-jdk-1.4.2/include/ ? -I/opt/blackdown-jdk-1.4.2/include/linux ? -L/opt/blackdown-jdk-1.4.2/jre/lib/i386/client? -ljvm -lpthread test.c jni.hと,jni.hの内部でincludeされているjni_md.hのある場所へのパスを通す必要がある. また,リンクすべきlibjvm.soへのリンクパスも必要 !実行 LD_LIBRARY_PATHにlibjvm.soのあるディレクトリが必要.私の環境では/opt/blackdown-jdk-1.4.2/ !GetStaticMethodID GetStaticMethodIDは,methodのIDを返す関数です. このとき,3番目の引数であるメソッドの名前と, 4番目の引数であるメソッドの引数を引数とします. この4番目の引数はJavaで定義されている内部表現によるものです. 型を自分で調べてもいいのですが, たとえばString[]の配列などは([Ljava/lang/String;)Vなどとなり,結構面倒です. なので,簡単に知るためにjavapというツールがあります. Test.classで定義されているmethodについて調べたければ, % javap -s Test とすることで, Compiled from Test.java public class Test extends java.lang.Test{ public Test(); /* ()V */ public stativ void testmthod(); /* ()V */ public int sumation(int, int); /* (II)I */ } などの表示を得ることができます.