美文网首页
Jni 学习之路--Jni 小知识库

Jni 学习之路--Jni 小知识库

作者: 老师好我是小明同学 | 来源:发表于2019-08-19 21:58 被阅读0次

一、Java 和 native 层对照知识点

1.返回值和参数类型对照表

Java类型 本地类型 描述
boolean jboolean C/C++8位整型
byte jbyte C/C++带符号的8位整型
char jchar C/C++无符号的16位整型
short jshort C/C++带符号的16位整型
int jint C/C++带符号的32位整型
long jlong C/C++带符号的64位整型e
float jfloat C/C++32位浮点型
double jdouble C/C++64位浮点型
Object jobject 任何Java对象,或者没有对应java类型的对象
Class jclass Class对象
String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组

2.native 层调用 java 类方法对照表

函数 Java数组类型 本地类型
GetBooleanArrayElements jbooleanArray jboolean
GetByteArrayElements jbyteArray jbyte
GetCharArrayElements jcharArray jchar
GetShortArrayElements jshortArray jshort
GetIntArrayElements jintArray jint
GetLongArrayElements jlongArray jlong
GetFloatArrayElements jfloatArray jfloat
GetDoubleArrayElements jdoubleArray jdouble
函数 描述
GetFieldID 得到一个实例的域的ID
GetStaticFieldID 得到一个静态的域的ID
GetMethodID 得到一个实例的方法的ID
GetStaticMethodID 得到一个静态方法的ID
Java 类型 符号
boolean Z
byte B
char C
short S
int I
long L
float F
double D
void V
objects对象 Lfully-qualified-class-name;L类名
Arrays数组 [array-type [数组类型
methods方法 (argument-types)return-type(参数类型)返回类型

二、Jni 实战

对于 Java 层调用 Native 层方法,在上一篇文章有介绍 Jni 学习之路--入门尝鲜详细教程

下面我们实战 Native 层调用 Java 层的例子

在 Simple.java 中,我们在 main 方法中创建一个 Point.java 对象,但这个对象不是像我们平时创建对象那样 new 处理,而是在 native 层使用 c 语言帮我们创建。具体代码实现如下。

Simple1.java

public class Simple {

    public static void main(String[] args) {
        
        Point point = createPoint();
        
        System.out.println("point: x = " + point.getX() +" , y = " + point.getY());
    }

    // native 方法构建而来
    private native static Point createPoint();

    static{
        System.load("E:/study/vsworkspace/StudyJniProject/x64/Debug/StudyJniProject2.dll");
    }

}

Point.java

public class Point {
    private int x;
    private int y;
    
    public Point(int x,int y){
        this.x = x;
        this.y = y;
    }
    
    public int getX() {
        return x;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public void setY(int y) {
        this.y = y;
    }
    
    public int getY() {
        return y;
    }
}

com_vegen_study_Simple.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_vegen_study_Simple */

#ifndef _Included_com_vegen_study_Simple 
#define _Included_com_vegen_study_Simple 
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jobject JNICALL Java_com_vegen_study_Simple_createPoint
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Simple.c

#include "com_vegen_study_Simple.h"

JNIEXPORT jobject JNICALL Java_com_vegen_study_Simple_createPoint
(JNIEnv *env, jclass jclz){
    // jclz 是 Simple.java

    // 获取 Point 的 class,参数 2:name = "全类名",注意不是 . 而是用 / 间隔
    jclass point_clz = (*env)->FindClass(env,"com/vegen/study/Point");
    // 构建 java 层的 Point 对象,j_mid 构造函数的 id , 构造方法 <init>,<II> 表示参数类型,V 表示返回类型
    jmethodID j_mid = (*env)->GetMethodID(env, point_clz, "<init>", "(II)V");

    jobject point = (*env)->NewObject(env, point_clz, j_mid, 100, 101);

    // 给 Point 的 y 赋值 ,调用它的 setY 方法
    j_mid = (*env)->GetMethodID(env, point_clz,"setY","(I)V");
    
    (*env)->CallVoidMethod(env, point, j_mid, 33);

    return point;
}

以上运行结果是 x = 100,y = 33

此文章讲解的是基础,在后面会讲解 c++ 的使用,以及 opencv、ndk 的相关内容,敬请期待。

参考:

1.https://www.cnblogs.com/daniel-shen/archive/2006/10/16/530587.html

2.https://www.jianshu.com/p/3dab1be3b9a4

相关文章

网友评论

      本文标题:Jni 学习之路--Jni 小知识库

      本文链接:https://www.haomeiwen.com/subject/tqlysctx.html