当前位置: 首页 > news >正文

基于JNI 实现 嵌套 List 类型参数解析

基于JNI 实现 嵌套 List 类型参数解析

    • 背景
    • 分析
    • 解决

背景

在前面两篇文章中,我们总结了Java 调用 C/C++ SDK 的几种方案,分享了JNI在实践过程中的一些踩坑点,而在这篇文章将继续分享针对Java List类型及其嵌套类型,我们的JNI如何接收。

分析

如下,是我的的SDK的结构体定义:

struct CustomParam{std::string key;std::vector<std::string> values;
};

SDK的请求体入参定义如下:

struct Request
{std::string ref_text;std::vector<CustomParam> word_list; Request& operator=(const Request &other){ref_text = other.ref_text;word_list = other.word_list;return *this;}
};

解决

● 根据上面的SDK结构体的相关定义,我们在Java层可以有如下的 类型定义:

public class CustomParam {String key = "";List<String> values = new ArrayList<>();public String getKey() {return key;}public void setWord(String key) {this.key = key;}public List<String> getValues() {return values;}public void setValues(List<String> values) {this.values = values;}
}

● 关于native的方法申明如下:

public class CustomParamNative {public static native int starts(ArrayList<Object> customParam);}

● 根据native方法生成 头部文件

javac -encoding utf8 -h . XXX.java

● 如下为生成的native方法的头部文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_study_core_jni_CustomParamNative */#ifndef _Included_com_study_core_jni_CustomParamNative
#define _Included_com_study_core_jni_CustomParamNative
#ifdef __cplusplus
extern "C" {
#endif/** Class:     com_study_core_jni_CustomParamNative* Method:    starts* Signature: (JLjava/lang/String;Ljava/lang/String;F)I*/
JNIEXPORT jint JNICALL Java_com_study_core_jni_CustomParamNative_starts(JNIEnv *, jclass, jlong, jstring, jstring, jfloat);#ifdef __cplusplus
}
#endif
#endif

● 头部文件的具体实现

#include "com_study_core_jni_CustomParamNative.h"
#include <vector>
#undef __request
#define __request Request#include "stdio.h"
#include "stdlib.h"JNIEXPORT jint JNICALL Java_com_study_core_jni_CustomParamNative_starts(JNIEnv *env, jclass obj, jstring jni_ref, jobject customParamList)
{__request request;CopyString(env, thread->text_buff, jni_ref);request.ref_text = thread->text_buff.data();CopyString(env, thread->text_buff, jni_utt);request.audio_id = thread->text_buff.data();if (customParamList != NULL){// 获取ArrayList类和对应的方法IDjclass arrayListClass = env->FindClass("java/util/ArrayList");jmethodID getMethodID = env->GetMethodID(arrayListClass, "get", "(I)Ljava/lang/Object;");jmethodID sizeMethodID = env->GetMethodID(arrayListClass, "size", "()I");// 获取CustomParam类和对应的字段IDjclass customParamClass = env->FindClass("com/seewo/study/core/bo/CustomParam");jfieldID wordFieldID = env->GetFieldID(customParamClass, "key", "Ljava/lang/String;");jfieldID valuesFieldID = env->GetFieldID(customParamClass, "values", "Ljava/util/List;");// 获取ArrayList的大小jint size = env->CallIntMethod(customParamList, sizeMethodID);printf("size = %d\n", size);// 遍历ArrayList并解析CustomParam对象for (int i = 0; i < size; i++){// 获取CustomParam对象jobject customParamObj = env->CallObjectMethod(customParamList, getMethodID, i);// 获取key字段的值jstring wordString = (jstring)env->GetObjectField(customParamObj, wordFieldID);printf("字符 = %c\n", wordString);jboolean is_copy;const char *word = env->GetStringUTFChars(wordString, &is_copy);printf("字符 = %c\n", word);// 将word和values赋值给C++结构体// 创建CustomParam结构体对象CustomParam customParam;// 将word字段的值赋值给C++结构体customParam.word = word;// 获取values字段的值jobject valuesList = env->GetObjectField(customParamObj, valuesFieldID);jclass listClass = env->FindClass("java/util/List");jmethodID toArrayMethodID = env->GetMethodID(listClass, "toArray", "()[Ljava/lang/Object;");jobjectArray valuesArray = (jobjectArray)env->CallObjectMethod(valuesList, toArrayMethodID);jsize size = env->GetArrayLength(valuesArray);std::vector<std::string> values;for (int j = 0; j < size; j++){jstring valuesString = (jstring)env->GetObjectArrayElement(valuesArray, j);const char *pron = env->GetStringUTFChars(valuesString, &is_copy);values.push_back(pron);env->ReleaseStringUTFChars(valuesString, pron);env->DeleteLocalRef(valuesString);}customParam.values = values;request.word_list.push_back(customParam);// 释放资源env->DeleteLocalRef(customParamObj);env->ReleaseStringUTFChars(wordString, word);env->DeleteLocalRef(wordString);env->DeleteLocalRef(valuesList);env->DeleteLocalRef(valuesArray);}// 释放资源env->DeleteLocalRef(arrayListClass);env->DeleteLocalRef(customParamClass);return ThreadHandleStarts<__request>(request);}}
http://www.lryc.cn/news/261452.html

相关文章:

  • 探索灵活性与可维护性的利器:策略(Strategy)模式详解
  • 压缩包文件暴力破解 -Server2005(解析)
  • mars3d加载arcgis发布的服务,⽀持4523坐标
  • 『K8S 入门』二:深入 Pod
  • 十七、如何将MapReduce程序提交到YARN运行
  • 华为云CodeArts Deploy常见问答汇总
  • 前后端交互—开发一个完整的服务器
  • 前端框架的虚拟DOM(Virtual DOM)
  • 什么是http状态码?
  • linux/CentOS 7安装Nginx
  • 软件工程期末复习+数据仓库ETL
  • 学习C语言——体会计算机中的0和1
  • PyTorch官网demo解读——第一个神经网络(1)
  • 升华 RabbitMQ:解锁一致性哈希交换机的奥秘【RabbitMQ 十】
  • vue3 element-plus 日期选择器 el-date-picker 汉化
  • 剑指 Offer(第2版)面试题 35:复杂链表的复制
  • 自定义指令Custom Directives
  • 预测性维护对制造企业设备管理的作用
  • 华为、新华三、锐捷常用命令总结
  • 链路追踪详解(四):分布式链路追踪的事实标准 OpenTelemetry 概述
  • Node.js 工作线程与子进程:应该使用哪一个
  • python matplotlib 三维图形添加文字且不随图形变动而变动
  • Ubuntu设置kubelet启动脚本关闭swap分区
  • MySQL数据库存储
  • verilog语法进阶,时钟原语
  • 案例069:基于微信小程序的计算机实验室排课与查询系统
  • C语言:将三个数从大到小输出
  • 基于Hadoop的铁路货运大数据平台设计与应用
  • Java基础题2:类和对象
  • 冒泡排序学习