一、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
网友评论