- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
{{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 */
}
などの表示を得ることができます.