Java 端代码
JniFuncMain.java
public class JniFuncMain{
private static int staticIntField = 300;
//加载本地库 jnifunc
static { System.loadLibrary("jnifunc");}
//本地方法声明
public static native JniTest createJniObject();
public static void main(String[] args){
//从本地代码生成 JniTest 对象
System.out.println("[Java] createJniObejct() 调用本地方法");
JniTest jniObj = createJniObject();
//调用 JniTest 对象的方法
jniObj.callTest();
}
}
JniTest.java
class JniTest{
private int intField;
//构造方法
public JniTest(int num){
intField = num;
System.out.println("[java] 调用JniTest对象的构造方法:intField = " + intField);
}
//此方法由JNI本地函数调用
public int callByNative(int num){
System.out.println("[Java] JniTest对象的callByNative("+ num +")调用");
return num;
}
public void callTest(){
System.out.println("[Java] JniTest对象的callTest()方法调用:intField="+intField);
}
}
生成C++头文件
编译 JniFuncMain.java
javac JniFuncMain.java
生成头文件
javah JniFuncMain
JniFuncMain.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniFuncMain */
#ifndef _Included_JniFuncMain
#define _Included_JniFuncMain
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniFuncMain
* Method: createJniObject
* Signature: ()LJniTest;
*/
JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
实现头文件中声明的函数
jnifunc.cpp
#include "JniFuncMain.h"
#include "stdio.h"
JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject(JNIEnv *env, jclass clazz){
jclass targetClass;
jmethodID mid;
jobject newObject;
jstring helloStr;
jfieldID fid;
jint staticIntField;
jint result;
//获取 JniFuncMain 类的 staticIntField 变量值
fid = env->GetStaticFieldID(clazz, "staticIntField", "I");
staticIntField = env->GetStaticIntField(clazz, fid);
printf("[CPP] 获取 JniFuncMain 类的 staticIntField 值\n");
printf("JnifuncMain.staticlntField = %d\n", staticIntField);
//查找生成对象的类
targetClass = env->FindClass("JniTest");
//查找构造方法
mid = env->GetMethodID(targetClass, "<init>", "(I)V");
//生成 JniTest 对象(返回对象的引用)
printf("[CPP] JniTest 对象生成\n");
newObject = env->NewObject(targetClass, mid, 100);
//调用对象的方法
mid = env->GetMethodID(targetClass, "callByNative", "(I)I");
result = env->CallIntMethod(newObject, mid, 200);
//设置JniTest 对象的 intField 值
fid = env->GetFieldID(targetClass, "intField", "I");
printf("[CPP] 设置 JniTest 对象的 intField 值为200\n");
env->SetIntField(newObject, fid, result);
//返回对象的引用
return newObject;
}
编译生成本地共享库
gcc -shared -fPIC -I /usr/lib/jvm/java-7-openjdk-amd64/include jnifunc.cpp -o libjnifunc.so
运行
java -Djava.library.path=. JniFuncMain
结果:
参考资料:
《Android框架揭秘》