一、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

本文深入探讨Java与Native层之间的交互原理,通过具体示例展示如何使用C语言在Native层创建并操作Java对象,同时提供详细的类型转换对照表及方法调用指南。
736

被折叠的 条评论
为什么被折叠?



