JNI对引用数据类型的操作

由于引用类型以不透明的方式传递给原生代码,因此引用类型不能直接使用和修改。但JNI提供了一些操作应用类型的API

本文主要介绍

  • 字符串
  • 数组
  • NIO缓冲区
  • 字段
  • 方法

基本数据类型

这里写图片描述

引用类型

这里写图片描述

1.创建字符串

jstring javaString;
javaString = (*env)->NewString(env,"HelloWorld");//创建Unicode字符串
javaString = (*env)->NewStringUTF(env,"HelloWorld");//创建UTF字符串

2.把Java字符串转换成C字符串

在原生代码中使用Java字符串需要先将其转换为C字符串

const jbyte* str;
jboolean isCopy;
str = (*env)->GetStringChars(env,javaString,&isCopy);//获得Unicode字符串
//GetStringUTFChars(env,javaString,&isCopy)//获得UTF字符串

if(str != 0){

}
//isCopy参数是一个可选参数,让调用者确定C字符串是指向副本还是堆中的固定对象。可选是 JNI_TRUE ,JNI_FALSE

3.释放字符串

JNI需要显式释放内存

(*env)->ReleaseStringChars(env,javaString,str);//Unicode
(*env)->ReleaseStringUTFChars(env,javaString,str);//UTF

4.数组

New< Type>Array Type可以使Int ,String ,Boolean ,Char

jintArray javaArray;
javaArray = (*env)->NewIntArray(env,10);//创建数组
jint nativeArray(10);
(*env)->GetIntArrayRegion(env,javaArray,0,10,nativeArray);//将java数组复制到给定的C数组中
(*env)->SetIntArrayRegion(env,javaArray,0,10,nativeArray);//将c数组复制回Java数组中


jint* nativeDirectArray;
jboolean isCopy;
nativeDirectArray = (*env)->GetIntArrayElements(env,javaArray,&isCopy);//   对直接指针操作
(*env)->ReleaseIntArrayElements(env,javaArray,nativeDirectArray,0);
// 第四个参数
// 0 复制内容,并释放原生数组
// JNI_COMMIT 复制内容,但不释放原生数组
// JNI_ABORT 释放原生数组,但不用复制内容

5.NIO操作

5.1创建直接字节缓冲区
unsigned char* buffer = (unsigned char*) malloc (1024);
jobject directBuffer;
directBuffer = (*env)->NewDirectByteBuffer(env,Buffer,1024);
5.2直接字节缓冲区获得
usigned char*  buffer;
buffer = (unsigned char*)(*env)->GetDirectBufferAddress(env,directBuffer);
5.3访问域
jclass clazz;
clazz = (*env)->GetObjectClass(env,instance);//获得类

获得实例域ID

jfieldID instanceFieldId;
instanceFieldId = (*env)->GetFieldID(env,clazz,"instanceField","Ljava/lang/String;");

获得静态域ID

jfieldID staticFieldId;
staticFieldId = (*env)->GetStaticFieldID(env,clazz,"staticField","Ljava/lang/String;")";

获取实例域

jstring instanceField;
instanceField = (*env)->GetObjectField(env,instance,instanceFieldId);

获取静态域

jstring staticField;
staticField = (*env)->GetStaticObjectField(env,clazz,staticFieldId);

6.调用方法

获取实例方法ID

jmethodID instanceMethodId;
instanceMethodId = (*env)->GetMethodID(env,clazz,"instanceMethod","()Ljava/lang/String;");

获取静态方法ID

jmethodID staticMethodId;
staticMethodId = (*env)->GetStaticMethodID(env,clazz,"staticMethod","()Ljava/lang/String;");

调用实例方法

jstring instanceMethodResult;
instanceMethodResult = (*env)->CallStringMethod(env,instance,instanceMethodId);//调用实例方法

jstring staticMethodResult;
staticMethodResult = (*env)->CallStaticStringMethod(env,clazz,staticMethodId);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JNI(Java Native Interface)是Java平台的一个组成部分,它允许Java代码与其他语言写的代码进行交互。当Java应用程序需要调用本地代码(如C或C++)时,就会使用JNI。 在JNI中,操作`BufferedImage`对象主要涉及到以下几个步骤: 1. **创建本地方法声明**:首先,你需要声明一个本地方法,该方法接受一个`BufferedImage`对象作为参数。这个方法通常用于加载图像或进行图像处理。 ```java public native void processImage(BufferedImage image); ``` 2. **生成JNI头文件**:使用`javah`工具从你的Java类生成JNI头文件。这个工具会生成一个包含本地方法声明的头文件。 ```bash javah -jni com.yourpackage.YourClass ``` 3. **实现本地方法**:使用C或C++实现这个本地方法。在这个方法中,你可以访问`BufferedImage`对象并进行处理。需要注意的是,在JNI中,所有的数据都是通过指针传递的,所以你需要正确地管理这些指针。 ```c JNIEXPORT void JNICALL Java_com_yourpackage_YourClass_processImage(JNIEnv *env, jobject obj, jobject image) { // 获取BufferedImage对象的指针 jobject realImage = (*env)->GetObjectField(env, image, (jfieldID) 0); BufferedImage *bufferedImage = (BufferedImage *) (*env)->GetIntField(env, realImage, (jfieldID) 0); // 在这里你可以对bufferedImage进行操作... } ``` 4. **编译并链接你的本地代码**:使用你的构建工具(如gcc或g++)编译你的本地代码,并链接到你的Java应用程序。 5. **在Java代码中调用本地方法**:最后,你可以在Java代码中调用这个本地方法,并传递一个`BufferedImage`对象作为参数。 请注意,JNI操作通常需要一些底层知识,包括内存管理、指针操作等。同时,你也需要注意Java的安全模型,以确保你的代码不会对系统造成危害。如果你不熟悉这些概念,我建议你寻求一些更详细的教程或资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值