java调用本地方法--jni访问实例域和静态域

2018-05-11  本文已影响82人  w1992wishes

本篇结构:

一、简介

接JNI简介的基础上,新增访问实例域的例子。

二、实例

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

最后运行。

上一篇下一篇

猜你喜欢

热点阅读