トップ 一覧 Farm 検索 ヘルプ RSS ログイン

C言語からJavaのメソッドを呼び出すの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
{{category プログラミング}}
{{category JAVA}}
{{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 <jni.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 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   */
 }

などの表示を得ることができます.