1.MainActivity.java
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 MainActiivty.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
我们需要这个文件中对两个native方法的声明来完成C文件(用完之后可以把它删除)
#include <jni.h>
JNIEXPORT void JNICALL Java_MainActivity_printHello(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}
JNIEXPORT void JNICALL Java_MainActivity_printString(JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
printf("%s\n", str);
}
3.编译c文件生成so文件,共java程序调用
若直接使用如下命令:gcc hellojni.c
编译报错:
hellojni.c:1:17: error: jni.h: 没有那个文件或目录
hellojni.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.<clinit>(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