java调用本地方法--jni访问实例域和静态域
2018-05-11 本文已影响82人
w1992wishes
本篇结构:
- 简介
- 实例
一、简介
接JNI简介的基础上,新增访问实例域的例子。
-
访问和修改实例变量操作步聚:
调用 GetObjectClass 函数获取实例对象的 Class 引用
调用 GetFieldID 函数获取 Class 引用中某个实例变量的 ID
调用 GetXXXField 函数获取变量的值,需要传入实例变量所属对象和变量 ID
调用 SetXXXField 函数修改变量的值,需要传入实例变量所属对象、变量 ID 和变量的值 -
访问和修改静态变量操作步聚:
调用 FindClass 函数获取类的 Class 引用
调用 GetStaticFieldID 函数获取 Class 引用中某个静态变量 ID
调用 GetStaticXXXField 函数获取静态变量的值,需要传入变量所属 Class 的引用和变量 ID
调用 SetStaticXXXField 函数设置静态变量的值,需要传入变量所属 Class 的引用、变量 ID和变量的值
二、实例
2.1、编写java类
public class Employee {
private String name;
private double salary;
static {
System.loadLibrary("Employee");
}
public native void raiseSalary(double byPercent);
public Employee(String n, double s){
this.name = n;
this.salary = s;
}
public void print(){
System.out.println(name + " " + salary);
}
}
public class EmployeeTest {
public static void main(String[] args) {
Employee[] staff = new Employee[3];
staff[0] = new Employee("Tom", 35000.0);
staff[1] = new Employee("Bob", 11000.0);
staff[2] = new Employee("Jane", 9999.0);
for (Employee e : staff) {
e.raiseSalary(5);
}
for (Employee e : staff) {
e.print();
}
}
}
2.2、编译java类
javac Employee.java
javac EmployeeTest.java
2.3、生成相关JNI方法的头文件
javah -d jnilib -jni Employee
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Employee */
#ifndef _Included_Employee
#define _Included_Employee
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Employee
* Method: raiseSalary
* Signature: (D)V
*/
JNIEXPORT void JNICALL Java_Employee_raiseSalary
(JNIEnv *, jobject, jdouble);
#ifdef __cplusplus
}
#endif
#endif
2.4、使用C/C++实现本地方法
#include "Employee.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_Employee_raiseSalary(JNIEnv* env, jobject this_obj, jdouble byPercent){
/* get the class */
jclass class_Employee = (*env)->GetObjectClass(env, this_obj);
/* get the field Id */
jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D");
/* get the field value */
jdouble salary = (*env)->GetDoubleField(env, this_obj, id_salary);
salary *= 1 + byPercent/100;
/* set the field value */
(*env)->SetDoubleField(env, this_obj, id_salary, salary);
}
jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D");中D代表类型double。
2.5、生成动态链接库
gcc -D_REENTRANT -fPIC -I $JAVA_HOME
/include -I $JAVA_HOME
/include/linux -shared -o libEmployee.so Employee.c
2.6、运行java
最后运行。