概述
JNI的程序一般都是调用Native函数,然后通过返回值返回对应结果。今天在测试的时候,发现一个要求需要实现类似C/C++ 引用那种方式,在Native函数对传递进来的参数进行修改,经过一番搜索,验证通过,博文记录,用以备忘。
Java代码
package org.leaf;
public class HelloJNI {
static {
System.loadLibrary("HelloJNI");
}
public static native void testObjRef(Long ret);
public static void main(String[] args) {
Long l = 123l;
testObjRef(l);
System.out.println("Hello world! long =" + l.toString());
}
}
JNI代码
头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_leaf_HelloJNI */
#ifndef _Included_org_leaf_HelloJNI
#define _Included_org_leaf_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_leaf_HelloJNI
* Method: testObjRef
* Signature: (Ljava/lang/Long;)V
*/
JNIEXPORT void JNICALL Java_org_leaf_HelloJNI_testObjRef
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
实现代码
#include "org_leaf_HelloJNI.h"
JNIEXPORT void JNICALL Java_org_leaf_HelloJNI_testObjRef
(JNIEnv *env, jobject obj, jobject longObject) {
jclass longClass = env->FindClass("java/lang/Long");
if (longClass == nullptr) {
// 处理错误情况
return;
}
// 然后,我们获取到存储long值的字段的ID
jfieldID valueFieldID = env->GetFieldID(longClass, "value", "J");
if (valueFieldID == nullptr) {
// 处理错误情况
env->DeleteLocalRef(longClass);
return;
}
// 修改Long对象的value字段,即改变其值
jlong newValue = 123456789L; // 新的值可以根据需要设置
env->SetLongField(longObject, valueFieldID, newValue);
// 清理
env->DeleteLocalRef(longClass);
}
测试结果
Q&A
Q:执行javah,提示程序找不到
A:在Java 10之后,该程序已经被废止,可使用javac -h代替
参考链接
java修改object里的值
jdk bin目录下找不到javah
visual studio2022 JNI极简开发流程