实现JNI中本地函数注册可以两种方式:
(1)采用默认的本地函数注册流程。
(2)自己重写JNI_OnLoad()函数。(本文介绍)(Android中采用这种)
JNI_OnLoad()作用是告知Android虚拟机JNI版本和进行jni函数里的一些初始化
Java端代码:
package com.jni;
public class JavaHello {
public static native String hello();
static {
try {
System.loadLibrary("test"); // load library: libtest.so
} catch (UnsatisfiedLinkError ule) {
System.err.println("WARNING: Could not load library!");
}
}
public static void main(String[] args) {
String s = new JavaHello().hello();
System.out.println(s);
}
}
本地C语言代码:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>
JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz) {
printf("hello in c native code.\n");
return (*env)->NewStringUTF(env, "hello world returned.");
}
#define JNIREG_CLASS "com/jni/JavaHello" // 指定要注册的类
/**
* Table of methods associated with a single class.
*/
static JNINativeMethod gMethods[] = {
{"hello", "()Ljava/lang/String;", (void *) native_hello}, // 绑定
};
/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *gMethods, int numMethods) {
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Register native methods for all classes we know about.
*/
static int registerNatives(JNIEnv *env) {
if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, sizeof(gMethods) / sizeof(gMethods[0])))
return JNI_FALSE;
return JNI_TRUE;
}
/*
* Set some test stuff up.
*
* Returns the JNI version on success, -1 on failure.
*/
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
assert(env != NULL);
if (!registerNatives(env)) {//注册
return -1;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
return result;
}
编译及运行流程:
1 设置三个环境变量:
export JAVA_HOME:=/usr/lib/jvm/java-6-sun-1.6.0.15
export JAVA_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/com/jfo
export NATIVE_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/jni
2 编译JavaHello.java:
javac $JAVA_SRC_PATH/JavaHello.java
3. 编译NativeHello.c,生成共享库
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c -o $NATIVE_SRC_PATH/NativeHello.o $NATIVE_SRC_PATH/NativeHello.c
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o $NATIVE_SRC_PATH/libtest.so $NATIVE_SRC_PATH/NativeHello.o
4. 运行
java com/jni/JavaHello
转自:http://blog.csdn.net/zhenyongyuan123/article/details/5862054