当前位置: 首页 > 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);}}

相关文章:

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

基于JNI 实现 嵌套 List 类型参数解析 背景分析解决 背景 在前面两篇文章中&#xff0c;我们总结了Java 调用 C/C SDK 的几种方案&#xff0c;分享了JNI在实践过程中的一些踩坑点&#xff0c;而在这篇文章将继续分享针对Java List类型及其嵌套类型&#xff0c;我们的JNI如何接…...

探索灵活性与可维护性的利器:策略(Strategy)模式详解

目录 ​编辑 1. 策略模式概述&#xff1a; 2. 主要角色&#xff1a; 3. 实例场景&#xff1a; 4. 具体实现步骤&#xff1a; 步骤一&#xff1a;定义策略接口 5. 使用策略模式的客户端代码&#xff1a; 总结&#xff1a; 我的其他博客 1. 策略模式概述&#xff1a; 策…...

压缩包文件暴力破解 -Server2005(解析)

任务五十一: 压缩包文件暴力破解 任务环境说明:Server2005 1. 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机服务版本信息,将 Telnet 版本信息字符串 作为 Flag 提交; flag:Microsoft Windows XP telnetd 2. 通过本地PC中渗透测试平台Kali对服务器场景Windows进行渗透测…...

mars3d加载arcgis发布的服务,⽀持4523坐标

问题 1.从这个服务地址加载&#xff0c;具体在哪⾥去转坐标呢&#xff1f; 加个 usePreCachedTilesIfAvailable&#xff1a;false 参数即可 坐标系为4490的arcgis影像服务图层&#xff0c;配置后瓦片加载不出来&#xff0c;没报错 甚至可以跳转 没有看出问题&#xff0c;或者测…...

『K8S 入门』二:深入 Pod

『K8S 入门』二&#xff1a;深入 Pod 一、基础命令 获取所有 Pod kubectl get pods2. 获取 deploy kubectl get deploy3. 删除 deploy&#xff0c;这时候相应的 pod 就没了 kubectl delete deploy nginx4. 虽然删掉了 Pod&#xff0c;但是这是时候还有 service&#xff0c…...

十七、如何将MapReduce程序提交到YARN运行

1、启动某个节点的某一个用户 hadoopnode1:~$ jps 13025 Jps hadoopnode1:~$ yarn --daemon start resourcemanager hadoopnode1:~$ jps 13170 ResourceManager 13253 Jps hadoopnode1:~$ yarn --daemon start nodemanager hadoopnode1:~$ jps 13170 ResourceManager 15062 Jp…...

华为云CodeArts Deploy常见问答汇总

1.【Deploy】部署java项目&#xff0c;为什么通过springboot启动步骤启动失败了&#xff1f; 答&#xff1a;用户所部署的jar包源码并不是springboot框架&#xff0c;所以无法用springboot启动步骤启动&#xff0c;该步骤并不等同于java -jar 命令&#xff0c;需要使用shell脚…...

前后端交互—开发一个完整的服务器

代码下载 初始化 新建 apiServer 文件夹作为项目根目录&#xff0c;并在项目根目录中运行如下的命令&#xff0c;初始化包管理配置文件: npm init -y运行如下的命令&#xff0c;安装 express、cors: npm i express cors在项目根目录中新建 app.js 作为整个项目的入口文件&a…...

前端框架的虚拟DOM(Virtual DOM)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

什么是http状态码?

什么是http状态码&#xff1f; 当浏览者访问一个网页时&#xff0c;浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前&#xff0c;此网页所在的服务器会返回一个包含 HTTP 状态码的信息头&#xff08;server header&#xff09;用以响应浏览器的请求。 ht…...

linux/CentOS 7安装Nginx

Nginx 是 C语言 开发&#xff0c;建议在 Linux 上运行&#xff0c;当然&#xff0c;也可以安装 Windows 版本&#xff0c;本篇则使用 CentOS 7 作为安装环境。 Nginx一般使用非root账号安装&#xff0c;如果还没有非root账号&#xff0c;先创建账号 创建账号 创建组&#xf…...

软件工程期末复习+数据仓库ETL

一、软件工程 请用基本路径测试方法为下列程序设计测试用例&#xff0c;并写明中间过程&#xff1a; 第1步&#xff1a;画出流程图 1.菱形用于条件判断。用在有分支的地方。 2.矩形表示一个基本操作。 3.圆形是连接点 第2步&#xff1a;计算程序环路复杂性 流图G的环路复杂…...

学习C语言——体会计算机中的0和1

/* 把hello隐写入一个整型数组,这个小程序可以考察是否清楚数据在内存中存储的具体细节。 具体的说&#xff0c;int类型在小端机器上的存储方式是高位在高地址&#xff0c;低位在低地址&#xff0c;从视觉习惯上和我们的日常书写习惯相反&#xff1b; char类型占用…...

PyTorch官网demo解读——第一个神经网络(1)

神经网络如此神奇&#xff0c;feel the magic 今天分享一下学习PyTorch官网demo的心得&#xff0c;原来实现一个神经网络可以如此简单/简洁/高效&#xff0c;同时也感慨PyTorch如此强大。 这个demo的目的是训练一个识别手写数字的模型&#xff01; 先上源码&#xff1a; fr…...

升华 RabbitMQ:解锁一致性哈希交换机的奥秘【RabbitMQ 十】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 升华 RabbitMQ&#xff1a;解锁一致性哈希交换机的奥秘【RabbitMQ 十】 前言第一&#xff1a;该插件需求为什么需要一种更智能的消息路由方式&#xff1f;一致性哈希的基本概念&#xff1a; 第二&…...

vue3 element-plus 日期选择器 el-date-picker 汉化

vue3 项目中&#xff0c;element-plus 的日期选择器 el-date-picker 默认是英文版的&#xff0c;如下&#xff1a; 页面引入&#xff1a; //引入汉化语言包 import locale from "element-plus/lib/locale/lang/zh-cn" import { ElDatePicker, ElButton, ElConfigP…...

剑指 Offer(第2版)面试题 35:复杂链表的复制

剑指 Offer&#xff08;第2版&#xff09;面试题 35&#xff1a;复杂链表的复制 剑指 Offer&#xff08;第2版&#xff09;面试题 35&#xff1a;复杂链表的复制解法1&#xff1a;模拟 剑指 Offer&#xff08;第2版&#xff09;面试题 35&#xff1a;复杂链表的复制 题目来源&…...

自定义指令Custom Directives

<script setup langts> import { ref } from "vue"const state ref(false)/*** Implement the custom directive* Make sure the input element focuses/blurs when the state is toggled* */ // 以v开头的驼峰式命名的变量都可以作为一个自定义指令 const VF…...

预测性维护对制造企业设备管理的作用

制造企业设备管理和维护对于生产效率和成本控制至关重要。然而&#xff0c;传统的维护方法往往无法准确预测设备故障&#xff0c;导致生产中断和高额维修费用。为了应对这一挑战&#xff0c;越来越多的制造企业开始采用预测性维护技术。 预测性维护是通过传感器数据、机器学习和…...

华为、新华三、锐捷常用命令总结

华为、新华三、锐捷常用命令总结 一、华为交换机基础配置命令二、H3C交换机的基本配置三、锐捷交换机基础命令配置 一、华为交换机基础配置命令 1、创建vlan&#xff1a; <Quidway> //用户视图&#xff0c;也就是在Quidway模式下运行命令。 <Quidway>system-view…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...