jniの簡単な使用
3233 ワード
1.MainActivity.java
MainActivityを生成する.class
2.hellojni.c
実行コマンド:javah-jni MainActivity
MainActivityを生成する.h
3.cファイルをコンパイルsoファイルを生成し、javaプログラム呼び出しを行う
gcc hellojni.c
コンパイルエラー:
hellojni.c:1:17: error: jni.h:そのファイルやディレクトリはありません.c:4: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’ hellojni.c:11: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
gccは自分のディレクトリの下でjniが見つからないからです.hこのヘッダファイル
最初は-l(Lの小文字)を使っていましたが、-I(iの大文字)のはずです.
gcc -shared -I/usr/lib/jvm/jdk1.6.0_32/include -I/usr/lib/jvm/jdk1.6.0_32/include/linux hellojni.c -o libHello.so
コンパイルエラー:
/usr/bin/ld:/tmp/ccV6179W.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC/tmp/ccV6179W.o: could not read symbols: Bad value collect2: ld returned 1 exit status
解決策は-fPICを追加することです
gcc -fPIC -shared -I/usr/lib/jvm/jdk1.6.0_32/include -I/usr/lib/jvm/jdk1.6.0_32/include/linux hellojni.c -o libHello.so
OK、コンパイルに成功してlibHelloを生成することができます.soファイル
4.javaプログラムの実行
コマンドこまんど:java MainActivity
エラー:
Exception in thread "main"java.lang.UnsatisfiedLinkError: no hellojni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738) at java.lang.Runtime.loadLibrary0(Runtime.java:823) at java.lang.System.loadLibrary(System.java:1028) at MainActivity.(MainActivity.java:20) Could not find the main class: MainActivity. Program will exit.
ロードするsoファイルが正しく見つかりません
次のようにする必要があります.
java -Djava.library.path=. MainActivity
現在のディレクトリでsoファイルを検索すると有名です.
すべてok、次の出力が表示されます.
yutao@yutao:~/デスクトップ$java-Djava.library.path=. MainActivity Hello World! Hello World, this string is from jni
public class MainActivity{
public static void main(String args[]) {
new MainActivity().printHello();
new MainActivity().printString("Hello World, this string is from jni");
}
static {
System.loadLibrary("Hello");
}
native void printHello();
native void printString(String str);
}
コンパイル:javac MainActivivty.java MainActivityを生成する.class
2.hellojni.c
実行コマンド:javah-jni MainActivity
MainActivityを生成する.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MainActivity */
#ifndef _Included_MainActivity
#define _Included_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MainActivity
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MainActivity_printHello
(JNIEnv *, jobject);
/*
* Class: MainActivity
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_MainActivity_printString
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
このファイルの2つのnativeメソッドに対する宣言が必要です.Cファイルを完了するには(使い終わったら削除できます)#include <jni.h>
JNIEXPORT void JNICALL Java_MainActivity_printHello(JNIEnv *env, jobject obj)
{
printf("Hello World!
");
}
JNIEXPORT void JNICALL Java_MainActivity_printString(JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
printf("%s
", str);
}
3.cファイルをコンパイルsoファイルを生成し、javaプログラム呼び出しを行う
gcc hellojni.c
コンパイルエラー:
hellojni.c:1:17: error: jni.h:そのファイルやディレクトリはありません.c:4: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’ hellojni.c:11: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
gccは自分のディレクトリの下でjniが見つからないからです.hこのヘッダファイル
最初は-l(Lの小文字)を使っていましたが、-I(iの大文字)のはずです.
gcc -shared -I/usr/lib/jvm/jdk1.6.0_32/include -I/usr/lib/jvm/jdk1.6.0_32/include/linux hellojni.c -o libHello.so
コンパイルエラー:
/usr/bin/ld:/tmp/ccV6179W.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC/tmp/ccV6179W.o: could not read symbols: Bad value collect2: ld returned 1 exit status
解決策は-fPICを追加することです
gcc -fPIC -shared -I/usr/lib/jvm/jdk1.6.0_32/include -I/usr/lib/jvm/jdk1.6.0_32/include/linux hellojni.c -o libHello.so
OK、コンパイルに成功してlibHelloを生成することができます.soファイル
4.javaプログラムの実行
コマンドこまんど:java MainActivity
エラー:
Exception in thread "main"java.lang.UnsatisfiedLinkError: no hellojni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738) at java.lang.Runtime.loadLibrary0(Runtime.java:823) at java.lang.System.loadLibrary(System.java:1028) at MainActivity.
ロードするsoファイルが正しく見つかりません
次のようにする必要があります.
java -Djava.library.path=. MainActivity
現在のディレクトリでsoファイルを検索すると有名です.
すべてok、次の出力が表示されます.
yutao@yutao:~/デスクトップ$java-Djava.library.path=. MainActivity Hello World! Hello World, this string is from jni