Linux环境下,java调用C/C++动态库

news2024/9/27 19:15:28

目录

一、环境准备

1、安装gcc/g++

2、下载jdk库并配置运行环境

二、配合Java程序创建C++程序的动态库

1、生成要求清单

2、交给C++ 去实现

(1) 接口函数实现

(2) 创建动态库

(3) 检查动态库是否正常链接

3、测试:Java程序调用C++动态库


一、环境准备

既然是同时需要用到 java 和 C/C++,java 的运行环境和编译C++ 的编译器自然就需要事先准备好

1、安装gcc/g++

# 安装gcc
sudo apt-get install gcc

# 安装g++
sudo apt-get install g++

2、下载jdk库并配置运行环境

jdk 是java依赖的软件工具包,运行java程序必不可少的要素。安装流程参考:JDK1.8

注意:记一下jdk的安装路径,下面要用

二、配合Java程序创建C++程序的动态库

Java程序调用的函数接口,是java程序决定的(比如函数名、形参、返回值)。C++只负责去实现,然后打包成动态库提供给Java。关于这个流程,可以这么理解:

  • Java 提供要求清单(接口函数的声明)
  • 交给C++去实现
  • C++实现以后,Java调用C++生成的动态库

1、生成要求清单

假设Java要调用的函数接口如下:

public class SVM {
    // Java 告诉C++:你帮我实现下面这个函数
    // native关键字不可省略
	public native int svm_dll_export(double[] random, String savepath);    
}

写好以后,现在我们要把清单转变成C++认识的模样,即.h文件。

生成命令:javac -h ./ SVM.java    ( ./ 和 SVM.java之间有一个空格)

注意:只要是一个普通类就可以,不需要加任何注释!不然会报错

2、交给C++ 去实现

(1) 接口函数实现

首先我们需要创建一个 SVM_DLL.cpp 文件,这个文件里放的是,上述接口函数的定义。这里可以把声明和定义分离,也可以放在一起,这里为了方便,就把声明和定义放在一起

第一步,把刚刚上面生成的 SVM.h 中的内容拷贝到 SVM_DLL.cpp 中

第二步,开始实现接口逻辑。jdoubleArray、jstring 是 jni 库提供的类型,是兼容java和C++数据类型的关键。我们要将 jdoubleArray 转换成 C++可以识别的类型。

基本类型的转化可以参考:jni基本类型的转换

jsstring / jdoubleArray类型的转换可以参考:jstring / jdoubleArray类型的转换

(2) 创建动态库

把实现上述代码逻辑时要用到的 .h 文件和 .c 文件放到同一个文件夹下。编写makefile,方便一键生成。

CC=g++              # 如果使用的是C,这里就是gcc;如果是C++,这里就是g++    
TARGET=libsvm.so    # 目标动态库文件
# 生成动态库所依赖的目标文件
TMPTARGET=SVM_DLL.o vacTestAcc.o vacSvmUtiles.o vacSvmClassify.o vacGetSampEn.o   
# 生成动态库需要的第三方头文件的搜索路径
COND=-std=c++11 \
	 -I/usr/local/java/jdk1.8.0_351/include/ \          # jdk安装目录下:jni.h(必须要有)
	 -I/usr/local/java/jdk1.8.0_351/include/linux/ \    # jdk安装目录下:jni_md.h(必须有)
	 -I/usr/local/include/eigen-3.3.9/ \              # 逻辑实现所需的第三方库目录(非必须)
	 -fpermissive     #(非必须)

$(TARGET):$(TMPTARGET)
	$(CC) -shared -o $@ $^ $(COND)
	rm $(TMPTARGET)            # 移除 .o 文件

%.o: %.cpp                             # 等价于下面的写法
	$(CC) -fPIC -c $< $(COND) 
#SVM_DLL.o:SVM_DLL.cpp                 # 下面的.cpp文件都是逻辑实现要用到的,等价于上面的写法
#	$(CC) -fPIC -o $(@) -c $^ $(COND)  
#vacTestAcc.o:vacTestAcc.cpp
#	$(CC) -fPIC -o $(@) -c $^ $(COND)
#vacGetSampEn.o:vacGetSampEn.cpp
#	$(CC) -fPIC -o $(@) -c $^ $(COND)
#vacSvmClassify.o:vacSvmClassify.cpp
#	$(CC) -fPIC -o $(@) -c $^ $(COND)
#vacSvmUtiles.o:vacSvmUtiles.cpp
#	$(CC) -fPIC -o $(@) -c $^ $(COND):

.PHONY:clean test
clean:
	rm $(TARGET)

在命令行输入:make。之后就会自动打包生成动态库。

(3) 检查动态库是否正常链接

输入 ldd -r 动态库名称 可以检查动态库的链接状况。这里我们输入:ldd -r libsvm.so

正常情况下:

异常情况下:

出现异常情况的原因大致有两种:

a. xx.cpp文件存在报错

        至于是哪个文件报错,可以输入“ c++filt 符号名 ”来确定是哪里出了问题,这里的符号名指的是_ZN10vacTestAcc16vacTestSampEnAccEPdiPKc

b. 逻辑实现时,某个要用的 .cpp 文件没有被编译生成 .o 文件。此时请检查 .o 文件是否有遗漏

3、测试:Java程序调用C++动态库

我们回到 Java 程序,Java调用动态库里的函数之前,需要先加载动态库。基本流程如下:

  • 加载动态库。System.load("动态库所在路径")
  • 调用库函数。
public class SVM {
	public native int svm_dll_export(double[] random, String savepath);
	
	public static void main(String[] args) throws InterruptedException{
        // 加载动态库
        System.load("/home/linux/Templates/workspace/svm/libsvm.so");  

		double[] arr = new double[]{1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0};
		String savepath = "../model";
        // 调用库函数
		int ret = new SVM().svm_dll_export(arr, savepath);                   
		System.out.println("C++计算返回的结果是: "+ ret);
	}
}

 测试结果:

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

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

相关文章

百万级数据以Excel形式导出

(1).主要考虑到两个方面&#xff0c;第一个方面是内存溢出问题&#xff0c;所以选用阿里的EasyExcel因为它对POI进行了封装功能强大&#xff1b;第二个方面是由于excel版本导致Sheet存储容量不一样&#xff0c;cexcel2003(.xls)每个Sheet只能存6万多条数据而cexcel2007(xlsx)能…

【自学Python】Python布尔型(bool)

Python布尔型(bool) Python布尔型(bool)教程 Python 布尔类型也叫 bool 类型&#xff0c;Python 布尔类型取值为 True 和 False。Python bool 类型的 True 表示条件为真&#xff0c; False 表示条件为假。 Python布尔型(bool) Python 中的布尔类型可以当做 整数 来对待&…

LeetCode 287. 寻找重复数难度中等2004

&#x1f308;&#x1f308;&#x1f604;&#x1f604;欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 287. 寻找重复数难度中等2004&#xff0c;做好准备了么&#xff0c;那么开始吧。&#x1f332;&#x1f332;&#x1f434;&#x1f434;一、题目名称LeetCo…

怎么在Gitee(码云)上传一个项目(一分钟)

目录怎么在Gitee&#xff08;码云&#xff09;上传一个项目1、工具1.1、Git1.2、新建仓库2、上传流程3、回答上传项目流程中的几个疑问&#xff1f;怎么在Gitee&#xff08;码云&#xff09;上传一个项目 1、工具 1.1、Git 在Git官网或者利用镜像下载符合自己电脑操作系统版…

小众企业在选购低代码平台时需要注意什么

编者按&#xff1a;企业个性化定制需求如何实现&#xff1f;本文介绍了小众企业在选择低代码平台需要注意的点&#xff0c;帮助企业选出更合适得的软件平台。关键词&#xff1a;源码交付&#xff0c;数据整合&#xff0c;前后端分离&#xff0c;私有化部署&#xff0c;安全技术…

IB生物笔记:细胞学说

国际学校生物老师从0开始解读IB生物&#xff0c;感兴趣的同学记得收藏哦~IB生物分为SL(standard level)和HL(higher level)SL有6个topic∶细胞生物&#xff0c;分子生物&#xff0c;遗传学&#xff0c;生态学&#xff0c;物种进化以及多样性和人体生理。HL除了上述6个topic外还…

【pat】出租

下面是新浪微博上曾经很火的一张图&#xff1a;一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#xff0c;index[1]0 对应 arr[0]8&#xff0c;index[2]3 对应 arr[3]0&#…

年底清货刻不容缓!3天清空库存的服装老板是怎么做到的?

春节气氛越来越浓厚&#xff0c; 服装人的心情却是越来越着急——眼看着要过年了&#xff0c;气候也马上回暖了&#xff0c;我店里的库存可咋办&#xff1f;做服装零售的老板都知道&#xff0c;大部分时候压垮服装店的不是淡季、不是租金、不是人工费&#xff0c;而是库存积压。…

Java IO流 - 对象序列化和对象反序列化

文章目录序列化对象对象序列化对象反序列化序列化对象 对象序列化 对象序列化概念: 作用&#xff1a;以内存为基准&#xff0c;把内存中的对象存储到磁盘文件中去&#xff0c;称为对象序列化。 使用到的流是对象字节输出流&#xff1a;ObjectOutputStream ObjectOutputStream构…

Navicat远程连接ubuntu数据库

关于这个问题&#xff0c;我看许多博主也给出了解答&#xff0c;但作者此次遇到的问题也是略微特殊&#xff0c;希望其他人遇到同样的问题能得到启发。 首先是MySQL的安装&#xff0c;我是用的是Xubuntu系统&#xff0c;按照ubuntu系统安装MySQL的步骤即可。如下&#xff1a; …

关系运算符shell

关系运算符只支持数字&#xff0c;不支持字符串&#xff0c;除非字符串的值是数字。下表列出了常用的关系运算符&#xff0c;假定变量 a 为 10&#xff0c;变量 b 为 20&#xff1a;运算符说明举例-eq检测两个数是否相等&#xff0c;相等返回 true。[ $a -eq $b ] 返回 false。…

Mask RCNN网络源码解读(Ⅲ) --- FCN网络

目录 1.FCN网络简介 2.FCN-32S 3.FCN-16S 4.FCN-8S 5.膨胀卷积&#xff08;空洞卷积&#xff09; 6.pytorch中FCN的实现 6.1 代码地址 1.FCN网络简介 首个端对端的针对像素级预测的全卷积网络。全卷积网络即将分类网络中的全连接层全部替换为卷积层。 从数据可以看出…

微服务自动化管理【etcd快速集群】

概述 1.etcd构建自身高可用集群主要有三种形式&#xff1a; 静态发现 预先已知etcd集群中有哪些节点&#xff0c;在启动时通过–initial-cluster参数直接指定好etcd的各个节点地址 etcd动态发现 静态配置前提是在搭建集群之前已经提前知道各节点的信息&#xff0c;而实际应用中…

使用VS Code创建第一个Flutter工程

一、前言 你可以使用任意文本编辑器&#xff0c;再结合命令行工具来开发 Flutter 应用。然而&#xff0c;我们推荐使用本文接下来介绍的编辑器插件以获取更好的开发体验。这些插件提供了代码补全、代码高亮、widget 辅助编辑的功能&#xff0c;以及为项目的运行和调试提供支持…

【Denial-of-Service on FPGA-based Cloud Infrastructures论文笔记】

基于FPGA的云基础设施拒绝服务摘要引言背景FPGA TechnologyFPGA设计的实现用户设计在AWS的注册用户设计在AWS上的部署基于FPGA的系统攻击与对策客户端的FPGA使用基于云的fpga的使用信息泄露错误注入攻击对策云FPGA上的拒绝服务攻击攻击模型AWS FPGA安全架构AWS EC2 F1强力锤击攻…

@Validated+循环依赖报错

目录 测试demo 回顾下三级缓存 循环依赖bean实例化初始化过程​​​​​​​ 源码解读 实例化myZmTest1 myZmTest1依赖myZmTest2&#xff0c;实例化2去注入 myZmTest2依赖myZmTest1&#xff0c;获取myZmTest1去注入 获取到myZmTest1&#xff0c;继续myZmTest2初始化 m…

TCP协议的三次握手与四次挥手(附带常见面试题)

目录 一.TCP/UDP的区别 二.三次握手 三.四次挥手 四.常见面试题 一.TCP/UDP的区别 TCP&#xff1a;TCP协议是面向连接&#xff0c;连接稳定可靠适用于网络连接连接较高的场景&#xff0c;可以准确无误的把数据传递给对方&#xff0c;但传输速度上可能会存在一定的延迟。TCP…

Leetcode.32 最长有效括号

题目链接 Leetcode.32 最长有效括号 题目描述 给你一个只包含 (和 )的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 1&#xff1a; 输入&#xff1a;s “(()” 输出&#xff1a;2 解释&#xff1a;最长有效括号子串是 “()”…

【报表设计器ActiveReportsJS(二)】第一个 ActiveReportsJS 报表设计器项目,本地化

上一篇&#xff1a;【Vue集成在线报表设计器ActiveReportsJS&#xff08;一&#xff09;】前言&#xff0c;ActiveReportsJS介绍&#xff0c; 在 Vue 框架中集成纯前端报表设计器 本篇将介绍如何使用ActiveReportsJS创建第一个web前端报表设计器 1. 创建 Vue应用 创建 Vue …

GNN笔记系列 5

GNN笔记系列 51.Permutation Equivariance of Graph Filters2.Lipschitz and Integral Lipschitz Filters3.Stability of Graph Filters to Scaling4.Stability of Graph Neural Networks to Scaling1.Permutation Equivariance of Graph Filters 图滤波器的置换等价性 引入置…