一 定义native方法,编译生成ray_JniTest.h头文件
public class JniTest {
int getRandomInt(int max) {
return new Random().nextInt(max);
}
static String getRandeomUUId() {
return UUID.randomUUID().toString();
}
public native void accessMethod();
public native void accessStaticMethod();
//访问构造方法
public native Date acceessConstructor();
}
ray_JniTest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class ray_JniTest */
#ifndef _Included_ray_JniTest
#define _Included_ray_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ray_JniTest
* Method: accessMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_ray_JniTest_accessMethod
(JNIEnv *, jobject);
/*
* Class: ray_JniTest
* Method: accessStaticMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_ray_JniTest_accessStaticMethod
(JNIEnv *, jobject);
/*
* Class: ray_JniTest
* Method: acceessConstructor
* Signature: ()Ljava/util/Date;
*/
JNIEXPORT jobject JNICALL Java_ray_JniTest_acceessConstructor
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
二 c中实现,生成 dll文件
#include "stdafx.h"
#include "ray_JniTest.h"
//访问非静态方法
JNIEXPORT void JNICALL Java_ray_JniTest_accessMethod
(JNIEnv * env, jobject jobj) {
//jclass
jclass jclz = (*env)->GetObjectClass(env, jobj);
//jmethodId
//方法的名字,方法的签名
jmethodID mid = (*env)->GetMethodID(env, jclz, "getRandomInt", "(I)I");
//调用
jint random = (*env)->CallIntMethod(env, jobj, mid, 200);
printf("C random: %d \n", random);
}
//JNI 访问Java 中的静态方法
JNIEXPORT void JNICALL Java_ray_JniTest_accessStaticMethod
(JNIEnv *env, jobject jobj) {
//jclass, 通过jobjcct 来搜索class,如果找到了,将这个class 转变成jclass,然后返回。
jclass clz = (*env)->GetObjectClass(env, jobj);
//jmethdId,GETStaticMethodID 方法的名字,方法的签名
jmethodID jmid = (*env)->GetStaticMethodID(env, clz, "getRandeomUUId", "()Ljava/lang/String;");
// 调用静态方法
jstring uuid = (*env)->CallStaticObjectMethod(env, clz, jmid);
//jstring -> char *
char * uuid_c = (*env)->GetStringUTFChars(env, uuid, NULL);
// uuid.txt
char filename[100];
sprintf(filename, "D://%s.txt", uuid_c);
FILE *fp = fopen(filename, "w");
fputs("I love jni", fp);
fclose(fp);
printf("文件写入成功\n");
}
//访问java构造方法
JNIEXPORT jobject JNICALL Java_ray_JniTest_acceessConstructor
(JNIEnv * env, jobject jobj) {
//通过类的路径来从JVM 里面找到对应的类
jclass jclz = (*env)->FindClass(env, "java/util/Date");
//jmethodid
jmethodID jmid = (*env)->GetMethodID(env, jclz, "<init>", "()V");
//调用 newObject 实例化Date 对象,返回值是一个jobjcct
jobject date_obj = (*env)->NewObject(env, jclz, jmid);
//得到对应对象的方法,前提是,我们访问了相关对象的构造函数创建了这个对象
jmethodID time_mid = (*env)->GetMethodID(env, jclz, "getTime", "()J");
jlong time = (*env)->CallLongMethod(env, date_obj, time_mid);
printf("time: %lld \n", time);
return date_obj;
}
三 加载dll,调用
public class JniTest {
int getRandomInt(int max) {
return new Random().nextInt(max);
}
static String getRandeomUUId() {
return UUID.randomUUID().toString();
}
public native void accessMethod();
public native void accessStaticMethod();
//访问构造方法
public native Date acceessConstructor();
static {
System.loadLibrary("lsn7");
}
public static void main(String[] args) {
JniTest jni_Test = new JniTest();
jni_Test.accessMethod();
jni_Test.accessStaticMethod();
jni_Test.acceessConstructor();
}
}
输出结果:
C random: 23
文件写入成功
time: 1584201437558
四 Demo
JNI获取Java中类方法、构造函数