Linux java jni调用C++封装动态库

        由于项目中java需要调用第三方提供的C++动态库;由于第三方动态库传入的参数较多,还伴随着指针传入操作,导致java调用极为不便!因此催生出对于第三方的C++动态库进行二次封装。java调用只需按结构传入一个结构化的string即可。话不多说开干!

第三方库

        第三方C++的头文件HD10_safe.h如下:

#ifndef _HD10_safe_H_
#define _HD10_safe_H_#ifdef _cplusplus
extern "C" {
#endiftypedef	enum VKeyGenResultEx
{KGRE_OK 	,KGRE_NOT_OK
}KeyGenResult;typedef enum ECUS
{BCM=1, DCM, IC_6000, GW, VWM, LDWS, DMS, VCU, RCU, ACC, RWCD, PSU, BBM, AC_6000, TPMS, VMS, PEPS, IMMO, EMS, ESCL,MMI, BMS, FC, EC, ECM, CPD_3000, AFS, TCO, TCU, DCU,ECAS, ABS, EBS, EPB, AEBS, EVM, TCU_SH, ADAS, BS_LKA, CIM,RIM, FIM, MCU, CABS, DSW, VCU_x5_M3S, SWG, CCU, WP_ECU, CMS_ECU,EHBS, ACR, TBOX_5G, CSC, HCU, LKA, ADCU, CPD_6000, IC_3000, AC_3000,LE_IC, LE_AC, LE_BCM, LE_GW, LE_VCU, LE_TPMS, LE_DCM, VDCU, PDU, DCDC, DCAC,         DSSAD
}ECUs;typedef unsigned char	uint8; 
typedef unsigned short	uint16;       
// Function
//
KeyGenResult HD10GenerateKeyEx(uint8*       iSeedArray,	/* Array for the seed [in] */uint8			iSeedArraySize,	/* Length of the array for the seed [in] */const uint8	iSecurityLevel,	/* Security level [in] */uint8 *		iKeyArray,	/* Array for the key [in, out] */uint8 *		iKeySize,	/* Length of the key [out] */ECUs			e			/* enum ECUS elements */);#ifdef _cplusplus
}
#endif#endif // _HD10_safe_H_

        第三方动态库 libTXJsafe.so 如下:

C++调用

        写一个C++ demo 调用动态库 test.cpp 代码如下:

#include <stdio.h>
#include "HD10_safe.h"int main()
{uint8 arr[2] = {0x12, 0x34};uint8 seed[2] = {0x00, 0x00};uint8 seedLen = 0;int ret = HD10GenerateKeyEx(arr, 2, 7, seed, &seedLen, TCU);printf("ret : %d, seedLen:%d \n", ret, seedLen);for(int i = 0; i < seedLen; i++){printf("seed[%d] : 0x%02x ;", i, seed[i]);}printf("\n");return 0;
}

        运行结果如下:

jni二次封装动态库

        通过jni二次封装动态库 mysafelib.cpp 代码如下:

#include <iostream>
#include <stdio.h>
#include <jni.h>
#include <string.h>
#include "HD10_safe.h"// iString 输入参数格式:level(1byte) + ECUS(1byte) + SeedSize(1byte) + SeedValue(nbyte)
// rString 返回参数格式:keysize(1byte) + keyValue(nbyte)
extern "C" {JNIEXPORT jstring JNICALL Java_com_example_MyClass_nativeMethod(JNIEnv *env, jobject obj, jstring iString);
}// 十六进制字符串转字十六进制 "12" --> 0x12
int Str2Hex(char *p_hexstr, int iHexLen, char *pdststr);// 十六进制数值转十六进制字符串 0x12 --> "12"
int Hex2Str(const char *p_strstr, int iStrLen, char *pdststr);JNIEXPORT jstring JNICALL Java_com_example_MyClass_nativeMethod(JNIEnv *env, jobject obj, jstring iString)
{char myRString[66] = {0};char iHexStrOrg[64] = {0};char iHexStr[32] = {0};const char *iStrData = env->GetStringUTFChars(iString, 0);memcpy(iHexStrOrg, iStrData, strlen(iStrData) > 64 ? 64 : strlen(iStrData));env->ReleaseStringUTFChars(iString, iStrData);int iHexStrLen = Str2Hex(iHexStrOrg, strlen(iHexStrOrg), iHexStr);// std::cout << "strlen(iHexStrOrg) : " << strlen(iHexStrOrg) << std::endl;if(iHexStrLen < 4)	return env->NewStringUTF(myRString);// std::cout << "iHexStrLen : " << iHexStrLen << std::endl;uint8 seed[32] = {0};uint8 key[33] = {0};uint8 keyLen = 0;uint8 u8Level		= *(uint8 *)iHexStr;uint8 u8ECU	 		= *(uint8 *)(iHexStr + 1);uint8 u8SeedSize	= *(uint8 *)(iHexStr + 2);// printf("u8SeedSize : %d \n", u8SeedSize);if(u8SeedSize > 32)	return env->NewStringUTF(myRString);memcpy(seed, iHexStr + 3, u8SeedSize);KeyGenResult ret = (KeyGenResult)HD10GenerateKeyEx(seed, u8SeedSize, u8Level, key + 1, &keyLen, (ECUs)u8ECU);if(ret != KGRE_OK || keyLen > 32)	return env->NewStringUTF(myRString);// printf("ret : %d, keyLen:%d \n", (int)ret, keyLen);// for(int i = 1; i <= keyLen; i++)	printf("key[%d] : %02x; ", i, key[i]);key[0] = keyLen * 2;Hex2Str((const char*)key, keyLen + 1, myRString);jstring rString = env->NewStringUTF(myRString);printf("\n---------------successful-----------------\n");return rString;
}// 十六进制字符串转字十六进制 "12" --> 0x12
int Str2Hex(char *p_hexstr, int iHexLen, char *pdststr)
{int iret = 0;while(p_hexstr != NULL && pdststr != NULL && iHexLen > 1){char cTemp = '0';// printf("1:%c, 2:%c\n", p_hexstr[0], p_hexstr[1]);// 小写统一转大写if(p_hexstr[0] >= '0' && p_hexstr[0] <= '9'){cTemp = p_hexstr[0] - '0';}else if(p_hexstr[0] >= 'A' && p_hexstr[0] <= 'F'){cTemp = p_hexstr[0] - 'A' + 10;}else if(p_hexstr[0] >= 'a' && p_hexstr[0] <= 'f'){cTemp = p_hexstr[0] - 'a' + 10;}else{printf("the hex str is error!\n");break;}*pdststr = cTemp * 16;if(p_hexstr[1] >= '0' && p_hexstr[1] <= '9'){cTemp = p_hexstr[1] - '0';}else if(p_hexstr[1] >= 'A' && p_hexstr[1] <= 'F'){cTemp = p_hexstr[1] - 'A' + 10;}else if(p_hexstr[1] >= 'a' && p_hexstr[1] <= 'f'){cTemp = p_hexstr[1] - 'a' + 10;}else{printf("the hex str is error!\n");break;}*pdststr += cTemp;// printf("---iHexLen:%d, pdststr:%c\n", iHexLen, *pdststr);iHexLen -= 2;p_hexstr += 2;pdststr++;iret++;}// printf("iret : %d\n", iret);return iret;
}// 十六进制数值转十六进制字符串 0x12 --> "12"
int Hex2Str(const char *p_strstr, int iStrLen, char *pdststr)
{int index_str = 0, index_hex = 0;const char cHex[] = "0123456789ABCDEF";while(index_str < iStrLen && p_strstr != NULL && pdststr != NULL){pdststr[index_hex++] = cHex[((uint8)p_strstr[index_str])/16];pdststr[index_hex++] = cHex[((uint8)p_strstr[index_str++])%16];}return index_hex;
}

        编译生成对应二次封装的动态库如下:

java调用二次封装动态库

        java调用二次封装库的demo文件如下:

package com.example;public class MyClass {static {System.load("/home/lijd/testlib3/sodir/libmysafe.so"); // 加载C++动态库}private native String nativeMethod(String str); // 声明本地方法public static void main(String[] args) {byte[] seedValue = new byte[]{0x12, 0x34};int seedSize = 2;//字节长度int level = 7;int ECUS = 29;StringBuffer param = new StringBuffer();param.append(byteToString(intToByte1(level)));param.append(byteToString(intToByte1(ECUS)));param.append(byteToString(intToByte1(seedSize)));param.append(byteToString(seedValue));String result = new MyClass().nativeMethod(param.toString()); // 调用本地方法System.out.println("---MyClass---" + result.length() + " : " + result);}/*** @title byteToString* @description 将字节数组转为字符串* @param buff*            字节数据* @return String 装换后的字符串数据*/public static final String byteToString(byte[] buff) {StringBuilder sb = new StringBuilder();if (null != buff && buff.length > 0) {for (byte b : buff) {short t = b;if (t < 0)t += 256;short h = (short) (t / 16);short l = (short) (t % 16);switch (h) {case 10:sb.append("A");break;case 11:sb.append("B");break;case 12:sb.append("C");break;case 13:sb.append("D");break;case 14:sb.append("E");break;case 15:sb.append("F");break;default:sb.append(h);break;}switch (l) {case 10:sb.append("A");break;case 11:sb.append("B");break;case 12:sb.append("C");break;case 13:sb.append("D");break;case 14:sb.append("E");break;case 15:sb.append("F");break;default:sb.append(l);break;}}}return sb.toString();}public static byte[] intToByte1(int value) {byte[] b = new byte[1];for (int i = 0; i < 1; ++i) {int offset = (b.length - 1 - i) * 8;b[i] = (byte) (value >>> offset & 255);}return b;}
}

        执行javac 编译源文件生产class文件如下:

        运行java的class文件如下:

        至此,一切搞定!通过windows测试这样也完全可以。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卧槽!这项目开源了!【送源码 】

随着科技的飞速发展&#xff0c;个人财务管理变得越来越重要。一个名为‘Maybe’的创新型个人财务与财富管理应用程序随之诞生&#xff0c;它以其丰富的功能和用户友好的界面受到了广大用户的关注。 现在项目方将这个价值 100万美元的个人理财应用项目开源了 Maybe Maybe应用…

吴恩达2022机器学习专项课程C2W2:2.19 sigmoid函数的替代方案 2.20如何选择激活函数 2.21 激活函数的重要性

这里写目录标题 引言sigmoid激活函数的局限1.回顾需求案例2.ReLU激活函数 常用的激活函数1.线性激活函数的解释 如何选择激活函数&#xff1f;1.选择输出层的激活函数2.选择隐藏层的激活函数 选择激活函数的总结1.输出层总结2.隐藏层总结3.TensorFlow设置激活函数 激活函数多样…

AI生成视频解决方案,降低成本,提高效率

传统的视频制作方式往往受限于高昂的成本、复杂的拍摄流程以及硬件设备的限制&#xff0c;为了解决这些问题&#xff0c;美摄科技凭借领先的AI技术&#xff0c;推出了全新的AI生成视频解决方案&#xff0c;为企业带来前所未有的视觉创新体验。 一、超越想象的AI视频生成 美摄…

大模型时代的具身智能系列专题(四)

google deepmind团队 谷歌旗下最大的两个 AI 研究机构——地处伦敦 DeepMind 与位于硅谷的 Google Brain 合并成立新部门 Google DeepMind。其将机器学习和系统神经科学的最先进技术结合起来&#xff0c;建立强大的通用学习算法。代表作有AlphaGo&#xff0c;AlphaStar&#x…

鸿蒙ArkTS声明式开发:跨平台支持列表【组件快捷键事件】

组件快捷键事件 开发者可以设置组件的自定义组合键&#xff0c;组合键的行为与click行为一致&#xff0c;组件在未获得焦点状态下也可以响应自定义组合键&#xff0c;每个组件可以设置多个组合键。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-s…

香橙派 AiPro通过Micro USB接口进行串口调试

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、配置步骤1.安装CH343驱动2.配置串口参数 二、使用步骤总结 前言 最近在玩一个新玩具香橙派 AiPro&#xff0c;除了通过SSH方式连接开发板以外&#xff0c;…

华为机考入门python3--(32)牛客32-密码截取

分类&#xff1a;最长对称子串、动态规划 知识点&#xff1a; 生成二维数组 dp [[0] * n for _ in range(n)] 求最大值 max(value1, value2) 动态规划的步骤 a. 定义问题 长度为n下最长的对称子串的长度 b. 确定状态 dp[i][j]表示字符串从索引i到j的子串是否为对称…

封装,static,代码块,对象的打印

封装&#xff0c;static&#xff0c;代码块&#xff0c;对象的打印 1. 封装1.1 封装的概念1.2 包的概念1.3 访问修饰限定符1.4 被封装的属性如何set和get&#xff1f; 2. static2.1 再谈学生类2.2 static修饰成员变量2.3 static修饰成员方法2.4 static成员变量初始化 3. 代码块…

IGMP——组播成员端网络协议

目录 一.IGMP基本概念 &#xff08;1&#xff09;组播转发困境 &#xff08;2&#xff09;感知组播成员方式 &#xff08;3&#xff09;IGMP版本 二.IGMP各版本的区别与联系 &#xff08;1&#xff09;IGMPV1 1.普遍组查询报文 2.成员关系报告报文 3.IGMPV1报文格式 4…

java第十七课 —— 递归

方法递归调用 递归就是方法自己调用自己&#xff0c;每次调用时传入不同的变量&#xff0c;递归有助于编程者解决复杂问题&#xff0c;同时可以让代码变得简洁。 递归重要规则 执行一个方法时&#xff0c;就创建一个新的受保护的独立空间&#xff08;栈空间&#xff09;。方…

922. 按奇偶排序数组 II - 力扣

1. 题目 给定一个非负整数数组 nums&#xff0c; nums 中一半整数是 奇数 &#xff0c;一半整数是 偶数 。 对数组进行排序&#xff0c;以便当 nums[i] 为奇数时&#xff0c;i 也是 奇数 &#xff1b;当 nums[i] 为偶数时&#xff0c; i 也是 偶数 。 你可以返回 任何满足上述…

微服务架构-异步消息传递设计模式

微服务架构-异步消息传递设计模式 异步消息允许服务发送消息后立即返回&#xff0c;而不需要等待消息被处理完毕&#xff0c;这种异步方式可以大大提高系统的处理速度、和吞吐量。 微服务架构&#xff0c;通常涉及多个服务之间的相互调用&#xff0c;如果通信只是在少数几个微…

lama-cleaner中的Paint-by-Example使用

Lama Cleaner是一个免费的、开源的、完全自托管的修复工具&#xff0c;里面提供了很多最前沿的AIGC模型。可以使用它从图片中删除任何不需要的物体、缺陷、人物&#xff0c;或删除和替换图片上的任何内容。本文章详细介绍了该工具的所有功能&#xff0c;并体验了下每个功能的实…

Shell编程之正则表达式与文本处理器

一、正则表达式 之前学习了 Shell 脚本的基础用法&#xff0c;已经可以利用条件判断、循环等语句编辑 Shell 脚本。接下来我们将开始介绍一个很重要的概念——正则表达式&#xff08;RegularExpression&#xff0c;RE&#xff09;。 1.1正则表达式概述 下面先来了解一下正则表…

BUUCTF---web---[BJDCTF2020]ZJCTF,不过如此

1、点开连接&#xff0c;页面出现了提示 传入一个参数text&#xff0c;里面的内容要包括I have a dream。 构造&#xff1a;?/textI have a dream。发现页面没有显示。这里推测可能得使用伪协议 在文件包含那一行&#xff0c;我们看到了next.php的提示&#xff0c;我们尝试读取…

卢文岩博士受邀参与中国科学院大学校友论坛 解码DPU核心价值

近日&#xff0c;第五届中国科学院大学校友创新论坛正式举行&#xff0c;本次论坛聚焦科技前沿领域&#xff0c;旨在搭建高端对话平台&#xff0c;促进产学研深度融合。在大算力时代——AI技术前沿沙龙上&#xff0c;中科驭数高级副总裁、CTO卢文岩博士受邀分享《DPU——连接算…

Mac | Mac 移动硬盘无法分区问题

现象问题 电脑配置&#xff1a;MacBook Pro M1&#xff0c;系统 Sonoma Mac 系统新升级了 Sonoma&#xff0c;结果出现各种问题。外接屏幕居然不能旋转 90 &#xff0c;查了一下是Sonoma系统导致的&#xff0c;以及莫名发热的问题。想着要么回退一下系统算了&#xff0c;于是网…

unity3D获取某天的0点和23点59分59秒

系列文章目录 unity工具 文章目录 系列文章目录unity工具 &#x1f449;一、前言&#x1f449;二、获取某一天的0点和23点59分59秒1-1.代码如下1-2.调用方法如下1-2-1.获取当天的时间1-2-2.获取某一天的时间 &#x1f449;三、当月第一天0时0分0秒&#x1f449;四、当月最后一…

3D点云焊缝提取 平面交线 投影

文章目录 1. 效果2. 思路3. 源码 1. 效果 2. 思路 计算点云法向量&#xff1b;计算点云位姿Pose;翻转Pose中的Z轴方向&#xff0c;使其一致&#xff1b;通过Pose的Z轴对点云进行方向过滤&#xff1b;对点云聚类&#xff1b;根据目标点云的高度提取目标点云&#xff1b;提取两块…

从 0 开始实现一个博客系统 (SSM 项目)

相关技术 Spring Spring Boot Spring MVC MyBatis Html Css JS pom 文件我就不放出来了, 之前用的 jdk8 做的, MySQL 用的 5.7, 都有点老了, 你们自己看着配版本就好 实现功能 用户注册 - 密码加盐加密 (md5 加密)前后端用户信息存储 - 令牌技术用户登录 - (使用 拦截…