一次JAVA调用C++的.so库的过程

1、准备好.so文件

2、java代码引入jna jar包

<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.9.0</version>
</dependency>

3、代码实现

package com.jimi.tracker.util;import com.google.common.collect.Lists;
import com.sun.jna.Library;
import com.sun.jna.Native;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;/*** Description:* <p>* SO的* </p>** @Author: leo.xiong* @CreateDate: 2023/12/27 20:19* @Email: xionglang@xxx.com* @Since:*/
public class JnaUtil {private static final Logger LOGGER = LoggerFactory.getLogger(JnaUtil.class);private static final String OS;private static final boolean IS_WIN;private static final String ENCODE = "encode";private static final String USR_LIB_JIMI_SO = "/usr/lib/jimi";private static final String SO = ".so";/*** 需要使用的so文件*/private static final List<String> SO_NAME_LIST = Lists.newArrayList(ENCODE);static {OS = System.getProperty("os.name").toUpperCase();IS_WIN = OS.contains("WIN");if (!IS_WIN) {//动态设置JNA参数,如果不动态设置,需要通过-Djna.library.path=/usr/lib/jimi/so 指定JVM参数,so文件名需要lib开头//System.setProperty("jna.library.path", USR_LIB_JIMI_SO + "/so");//在当前jar包的resouce/so文件夹,把so文件放入其中extractSoFromJar(JnaUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(), USR_LIB_JIMI_SO);}}/*** 加载Jar包中的so文件** @param jarPath* @param extractPath*/private static void extractSoFromJar(String jarPath, String extractPath) {File jarFile = new File(jarPath);try (JarFile jar = new JarFile(jarFile)) {Enumeration<JarEntry> entries = jar.entries();while (entries.hasMoreElements()) {JarEntry entry = entries.nextElement();if (!entry.getName().toLowerCase().endsWith(SO)) {continue;}boolean isCopy = false;for (String soName : SO_NAME_LIST) {if (entry.getName().contains(soName)) {isCopy = true;}}if (!isCopy) {continue;}File outputFile = new File(extractPath, entry.getName());if (outputFile.exists()) {//文件已存在,先删除旧的so文件LOGGER.info("文件已存在,先删除旧的so文件:{}", extractPath + "/" + entry.getName());outputFile.delete();}outputFile = new File(extractPath, entry.getName());if (!outputFile.getParentFile().exists()) {outputFile.getParentFile().mkdirs();}try (InputStream is = jar.getInputStream(entry);OutputStream os = new FileOutputStream(outputFile)) {byte[] buffer = new byte[1024];while (is.read(buffer) > 0) {os.write(buffer);}} catch (IOException ioException) {LOGGER.warn("读取.so文件失败 fileName: {}", entry.getName(), ioException);}}} catch (IOException ioException) {LOGGER.warn("获取.so库失败 jarPath: {} extractPath: {}", jarPath, extractPath, ioException);}}/*** 调用C加密库** @param imei* @param chipId* @param type* @return*/public static String encryptValue(String imei, String chipId, Integer type) {//返回值最大32个字节,根据实际情况设置,后面trim去掉未使用的字节位置byte[] encryptBytes = new byte[32];try {if (IS_WIN) {return imei;}EncodeLibrary.INSTANCE.ImeiChipEncrypt(encryptBytes, imei, chipId, type);} catch (Exception e) {LOGGER.warn("加密值获取错误 imei:{} chipId: {} type: {}", imei, chipId, type, e);return null;}return new String(encryptBytes, StandardCharsets.UTF_8).trim();}/*** 调用加密方法*/public interface EncodeLibrary extends Library {/*** 加密文件名称,指定 JVM参数,文件放在这个路径下面 -Djna.library.path=/usr/lib* linux 文件名使用lib开头,如文件名【libencode.so】,加载的时候需要去掉lib,使用【encode】*/EncodeLibrary INSTANCE = Native.load(ENCODE, EncodeLibrary.class);/*** 调用C++加密方法,名称跟.h文件相同** @param output* @param imei* @param chip* @param mode*/void ImeiChipEncrypt(byte[] output, String imei, String chip, Integer mode);}public static void main(String[] args) {byte[] encryptBytes = new byte[32];EncodeLibrary.INSTANCE.ImeiChipEncrypt(encryptBytes, "123456789123123456789", null, 0);}
}

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

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

相关文章

Linux文件系统中的目录

目录说明/Linux操作系统所有目录的入口binbinaries缩写&#xff0c;存放二进制可执行文件sbinsuperuser binaries缩写&#xff0c;存放二进制可执行文件&#xff0c;只有root才能访问etcetcetera缩写&#xff0c;存放系统配置文件usrunix sharedresources缩写&#xff0c;用于存…

K8s攻击案例:组件未授权访问导致集群入侵

K8s集群往往会因为组件的不安全配置存在未授权访问的情况&#xff0c;如果攻击者能够进行未授权访问&#xff0c;可能导致集群节点遭受入侵。比较常见的的组件未授权访问漏洞&#xff0c;主要包括 API Server 未授权访问、kubelet 未授权访问、etcd 未授权访问、kube-proxy 不安…

C++系列-第1章顺序结构-4-整型int

C系列-第1章顺序结构-4-整型int 在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.cn/ 总结 本文是C系列博客&#xff0c;主要讲述整型int的用法 整型int 在C中&#xff0c;int 是一个关键字&#xff0c;用于声明整型变量。int 类型用于存储整数&…

01的token的年度总结

​ 大家好&#xff0c;我是token&#xff0c;一个热爱.NET的普通人&#xff0c;同样我来自湖南衡阳&#xff0c;再次之前我已经遇到非常多的湖南衡阳的老乡&#xff0c;比如李哥。 ​ 在这里一年中&#xff0c;我的成长也是非常迅速的&#xff0c;每一年的的每一天&#xff0c…

【Linux】深挖进程地址空间

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟悉【Linux】进程地址空间 > 毒鸡汤&#xff…

Thinkphp+vue+mysql学生作业管理系统21j0r

运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp5 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat/phpmyadmin 为设计一个安全便捷&#xff0c;并且使用户更好获取本学院…

解决jenkins、git拉取代码仓库失败Please make sure you have the correct access rights

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

Redis主从

一、为何需要主从 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离 二、如何设置主从 有临时和永久两种模式&#xff1a; 修改配置文件&#xff08;永久生效&#xff09; 在redis.conf中添…

C语言计算三阶行列式

文章目录 1-13题例题14参考答案1参考答案2 1-13题 C语言基础例题1-3题-指针篇 C语言基础例题4-5题-二维数组篇 C语言基础例题6-7题-结构体篇 C语言基础例题8-9题-大作业篇 C语言基础例题10-11题-字符串、指针篇 C语言基础例题12题-链表 C语言基础例题13题-字符串逆序 例题14 …

oracle怎么创建反向索引,解决enq:TX - index contention

有时候发生激烈的索引竞争的话&#xff0c;例如有大量的等待事件&#xff1a;enq&#xff1a;TX - index contention&#xff0c;此时可能需要创建反向索引解决&#xff0c;那么如何创建呢&#xff1f;下面是创建反向索引的实验过程&#xff1a; – 创建两张相同结构的表&…

【23.12.29期--Spring篇】Spring的 IOC 介绍

介绍一下Spring的IOC ✔️引言✔️ lOC的优点✔️Spring的IOC✔️ 拓展知识仓✔️IOC是如何实现的&#xff1f; ✔️引言 所谓的IOC (inversion of control) &#xff0c;就是控制反转的意思。何为控制反转? 在传统的程序设计中&#xff0c;应用程序代码通常控制着对象的创建和…

Typora使用PicGo+Gitee上传图片

Typora使用PicGoGitee上传图片 1.下载PicGo(国内镜像) https://mirrors.sdu.edu.cn/github-release/Molunerfinn_PicGo/ 点击PicGo-Setup-2.3.0-x64.exe &#xff08;64位安装&#xff09; 然后打开gitee&#xff08;没注册先注册&#xff09; 2.下载node.js插件 https:/…

Android Camera

1. 相关的API Android有三套关于摄像头的API(库)&#xff0c;分别是Camera、Camera2和CameraX&#xff0c;其中Camera已废弃&#xff0c;在Android5.0以后推荐使用Camera2和CameraX&#xff0c;Camera2推出是用来替换Camera的&#xff0c;它拥有丰富的API可以为复杂的用例提供…

算法与数据结构--二叉搜索树与自平衡二叉搜索树

0.字典&#xff08;即c的map&#xff09; 注&#xff1a;字典的 "member运算" 指的是检查字典中是否存在某个特定的键的操作&#xff0c;即查询操作。 如果我们使用数组来实现字典/map&#xff0c;虽然使用二分法查询也可以达到logn&#xff0c;但是的话插入和删除太…

SourceTree的安装和使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装&#xff1a;二、使用步骤1.获取地址2.放入sourceTree 3.点击推送 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 简单讲解一…

XV7001BB陀螺传感器

XV7001BB是一款工业级的高精度角度测量仪器&#xff0c;具备SPI或i2c串行接口&#xff0c;能够输出16位的角速率数据。同时&#xff0c;内置温度传感器可以实时监测环境温度&#xff0c;可选数字滤波器可以有效降低噪声干扰&#xff0c;使得测量结果更加准确可靠。作为一款低功…

Apache OFBiz 远程代码执行漏洞(CVE-2023-51467)

产品简介 Apache OFBiz是一个电子商务平台&#xff0c;用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。 漏洞概述 该系统的身份验证机制存在缺陷&#xff0c;可能允许未授权用户通过绕过标准登录流程来获取后台访问权限。此外&…

Docker常用命令详细整合

超详细Docker整合笔记可看&#xff1a;尚硅谷Docker基础篇和Dockerfile超详细整合笔记-CSDN博客 ———————————————————————————— Docker常用命令&#xff1a; 帮助启动类命令&#xff1a; 启动docker&#xff1a; systemctl start docker 停止…

Visual Studio Code 中,通过显示波浪线来提示代码中存在的错误或警告

在Visual Studio Code (VSCode)中&#xff0c;编辑器会通过显示波浪线&#xff08;也称为squiggles&#xff09;来提示代码中存在的错误或警告。这些波浪线的颜色通常为红色表示错误&#xff0c;黄色表示警告。 1. 自定义错误和警告提示 • 打开设置&#xff1a;点击左上角菜单…

WebService

调试工具&#xff1a;Postman、SoapUI Soap WebService :.net WCF 、Java CFX WebService三要素&#xff1a; SOAP&#xff08;Simple Object Access Protocol&#xff09;&#xff1a;用来描述传递信息的格式&#xff0c; 可以和现存的许多因特网协议和格式结合使用&#x…