当前位置:网站首页>【混合编程jni 】第六篇之native 中字符串和数组的操作
【混合编程jni 】第六篇之native 中字符串和数组的操作
2022-06-26 22:01:00 【华为云】
继续JNI的知识点,今天看下字符串和数组的一些操作
这两个是比较特殊的存在
字符串操作
编码格式
Java默认使用Unicode编码,C/C++默认使用UTF编码
在本地代码中操作字符串的时候,JNI支持字符串在Unicode和UTF-8两种编码之间转换。
GetStringUTFChars能够把一个jstring指针(指向JVM内部的Unicode字符序列)转换成一个UTF-8格式的C字符串。
访问字符串
一般来说,在从JVM内部获取一个字符串之后。
JVM内部会分配一块新的内存,拷贝原来的字符串,以便本地代码访问和改动。
即然有内存分配。在使用完之后就应该释放。
ReleaseStringUTFChars()和GetStringUTFChars()必须成对出现,用来释放内存和引用,使对象可以被GC回收。
创建字符串
调用NewStringUTF函数会构建一个新的java.lang.String字符串对象。
JVM不能分配足够的内存,NewStringUTF会抛出一个OutOfMemoryError异常,并返回NULL
下面是一套连招
jstring NewStringUTF(JNIEnv *env, const char *bytes); jsize GetStringUTFLength(JNIEnv *env, jstring string);void ReleaseStringUTFChars(JNIEnv *env, jstring string,const char *utf);两组函数 GetStringRegion 和 GetStringUTFRegion
void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);上述两个函数是复制一段内容倒buff 数组中,避免了全部拷贝。
推荐使用GetStringUTFRegion
GetStringCritical和ReleaseStringCriticalconst jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);GetStringCritical得到的是一个指向JVM内部字符串的直接指针,获取这个直接指针后会导致暂停GC线程这里传递的是jvm内部的指针,一定要小心,慎用
数组操作
数组的操作命名规则都是 operate + PrimitiveType + Array
先通过GetXXXArrayElements函数把简单类型的数组转化成本地类型的数组,
并返回其数组的指针,然后通过该指针来对拷贝数组进行处理。
对拷贝数组处理完后,通过ReleaseXXXArrayElements函数把修改后的拷贝数组的反射到java数组,
基本操作
// 获得数组长度jsize (GetArrayLength)(JNIEnv env, jarray array);// 创建数组jobjectArray NewObjectArray (JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);// 获取元素NativeType *Get<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, jboolean *isCopy);// 设置数据void SetObjectArrayElement(JNIEnv *env, jobjectArray array,jsize index, jobject value)// 释放元素void Release<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, NativeType *elems, jint mode);elems 参数是一个通过使用对应的GetPrimitiveTypeArrayElements() 函数由 array 导出的指针。
必要时,该函数将把对 elems 的修改复制回基本类型数组。mode参数将提供有关如何释放数组缓冲区的信息。
如果elems 不是 array 中数组元素的副本,mode将无效。
否则,mode 将具有下表所述的功能:

局部访问
// 将数组内容复制到 C 缓冲区内void Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);// 将缓冲区内的内容复制到数组上void Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, const NativeType *buf);用来将基本类型数组某一区域复制到缓冲区中的一组函数/将基本类型数组的某一区域从缓冲区中复制回来的一组函数
直接访问
void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);返回一个指定基础数据类型数组的直接指针,在这两个操作之间不能做任何阻塞的操作
来个例子
传递数组到C++
// Java 传递 数组 到 C++ 进行数组求和 private native int intArraySum(int[] intArray, int size);C++ 侧代码
JNIEXPORT jint JNICALLJava_com_demo_intArraySum(JNIEnv *env, jobject instance, jintArray intArray_, jint num) { jint *intArray; int sum = 0; // 操作方法一: // 如同 getUTFString 一样,会申请 native 内存 intArray = env->GetIntArrayElements(intArray_, NULL); if (intArray == NULL) { return 0; } // 得到数组的长度 int length = env->GetArrayLength(intArray_); cout<<"array length is "<<length; for (int i = 0; i < length; ++i) { sum += intArray[i]; } cout<<"sum is " <<sum); // 操作方法二: jint buf[num]; // 通过 GetIntArrayRegion 方法来获取数组内容 env->GetIntArrayRegion(intArray_, 0, num, buf); sum = 0; for (int i = 0; i < num; ++i) { sum += buf[i]; } cout<<"sum is "<<sum; // 使用完了别忘了释放内存 env->ReleaseIntArrayElements(intArray_, intArray, 0); return sum;}C++返回数组给Java
// 从 C++ 返回基本数据类型数组 private native int[] returnIntArray(int num);/** * 从 Native 返回 int 数组,主要调用 set<Type>ArrayRegion 来填充数据,其他数据类型类似操作 */extern "C"JNIEXPORT jintArray JNICALLJava_demo_returnIntArray(JNIEnv *env, jobject instance, jint num) { jintArray intArray; intArray = env->NewIntArray(num); jint buf[num]; for (int i = 0; i < num; ++i) { buf[i] = i * 2; } // 使用 setIntArrayRegion 来赋值 env->SetIntArrayRegion(intArray, 0, num, buf); return intArray;}总结
这篇主要写了字符串和数组的操作
基本上要记住的就是get ,set ,region 以及release 几个关键词
申请内存,释放内存,获取元素,操作元素
边栏推荐
- 这个算BUG吗?乱填的字母是否可以关闭
- Is this a bug? Whether the randomly filled letters can be closed
- 请问CMS里UniAPP版本中的&ldquo;自定义表单列表如何去掉?
- numpy中mgrid的用法
- Netease Yunxin officially joined the smart hospital branch of China Medical Equipment Association to accelerate the construction of smart hospitals across the country
- Configure redis master-slave and sentinel sentinel in the centos7 environment (solve the problem that the sentinel does not switch when the master hangs up in the ECS)
- 大龄程序员的一些出路
- Is there any risk for flush to register and open an account? Is it safe?
- SAP Spartacus 默认路由配置的工作原理
- 打新债注册开户有没有什么风险?安全吗?
猜你喜欢

Unity: the referenced script (unknown) on this behavior is missing“

360 mobile assistant is the first to access the app signature service system to help distribute privacy and security

VB. Net class library - 4 screen shots, clipping

What are the accounting elements

Data governance does everything

线性模型LN、单神经网络SNN、深度神经网络DNN与CNN测试对比
![leetcode:710. Random numbers in the blacklist [mapping thinking]](/img/ec/a3faeae6636bc3d0d9536962fdd9af.png)
leetcode:710. Random numbers in the blacklist [mapping thinking]

Unity: 脚本缺失 “The referenced script (Unknown) on this Behaviour is missing!“

数据治理啥都干

MATLAB and MySQL database connection and data exchange (based on ODBC)
随机推荐
「连续学习Continual learning, CL」最新2022研究综述
如何在 SAP BTP 平台上启用 HANA Cloud 服务
DLA model (classification model + improved segmentation model) + deformable convolution
Is there any risk for flush to register and open an account? Is it safe?
在哪家证券公司开户最方便最安全可靠
DAST black box vulnerability scanner part 5: vulnerability scanning engine and service capability
Fastadmin Aurora push send message registration_ Multiple IDs are invalid after being separated by commas
Using C to operate SQLSERVER database through SQL statement tutorial
网络连接断开请刷新重试
简析攻防演练中蓝队的自查内容
The network connection is disconnected. Please refresh and try again
Is there any risk in opening a securities registration account? Is it safe?
How to create an OData service with the graphical modeler on the sap BTP platform
在Flutter中解析复杂的JSON
简述unity的模型动画功能
【题解】剑指 Offer 15. 二进制中1的个数(C语言)
Different subsequence problems I
2022年,中轻度游戏出海路在何方?
The sharp sword of API management -- eolink
[bug feedback] the problem of message sending time of webim online chat system