java调用c++,使用clion进行JNI开发,ddl包生成以及so包生成

news2024/11/27 14:51:51

java调用c++,使用clion进行JNI开发,ddl包生成以及so包生成

    • java基础代码
    • 生成C++头部文件
    • 使用clion写C++实现代码
    • cmke打包构建使用
    • java调用C++执行
    • linux环境下产生CPP的so包

java基础代码

先写好对应的基础代码,先不管static加载的ddl文件,这里的ddl是后面c++代码打包生成的,使用绝对路径即可

package com.chw.gateway;

/**
 * JNI开发
 */
public class JavaWithCppApplication {
    static {
        System.load("E:\\document\\CLionProjects\\testDDL2\\cmake-build-debug\\libtestDDL2.dll");
    }

    public native int add(int a, int b);

    public native int sendSty(Student student);

    public static void main(String[] args) {
        JavaWithCppApplication obj = new JavaWithCppApplication();

        int result = obj.add(3, 5);

        System.out.println("Result: " + result);

        Student student = new Student("chw", 3);
        System.out.println("id:" + obj.sendSty(student));
    }
}

package com.chw.gateway;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.Serializable;

@Data
@AllArgsConstructor
public class Student implements Serializable {

    private String name;

    private Integer stuId;

}

生成C++头部文件

使用javah 生成对应的头部文件,因为c++与java交互的头部文件相对复杂,初学者还是直接生成比较好,后面需要添加方法再自己手动添加,如果类再包里面,就指定报名,如果没有再package里,就直 javah 类名 就可以了

javah com.chw.gateway.JavaWithCppApplication 

生成的C++头部文件如下 JavaWithCppApplication.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_chw_gateway_JavaWithCppApplication */

#ifndef _Included_com_chw_gateway_JavaWithCppApplication
#define _Included_com_chw_gateway_JavaWithCppApplication
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_chw_gateway_JavaWithCppApplication
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT int JNICALL Java_com_chw_gateway_JavaWithCppApplication_add
        (JNIEnv *, jobject, jint, jint);

JNIEXPORT int JNICALL Java_com_chw_gateway_JavaWithCppApplication_sendSty
        (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

使用clion写C++实现代码

clion构建c++依赖库的话选择library进行创建项目
在这里插入图片描述
如下引入头文件后,实现我们的方法(JavaWithCppApplication.cpp)。 JavaWithCppApplication.h头文件中引用到了jni.h,这是个java与c++交互的头文件,可以到java安装目录下找win版本的可以在 D:\software\Java\jdk1.8.0_221\include\jni.hD:\software\Java\jdk1.8.0_221\include\win32\jni_md.h 可以把这两个文件直接复制到c++项目路径下。

//
// Created by chw on 2024/3/18.
//
#include <iostream>
#include "JavaWithCppApplication.h"


JNIEXPORT int JNICALL Java_com_chw_gateway_JavaWithCppApplication_add
        (JNIEnv *, jobject, jint a, jint b) {
    return a + b;
}

JNIEXPORT int JNICALL Java_com_chw_gateway_JavaWithCppApplication_sendSty
        (JNIEnv *env, jobject temp, jobject obj) {
    jclass jcs = env->FindClass("com/chw/gateway/Student");
    jfieldID fileStuId = env->GetFieldID(jcs, "stuId", "Ljava/lang/Integer;");
    jobject intObj = env->GetObjectField(obj, fileStuId);

    jclass intClass = env->FindClass("java/lang/Integer");
    jmethodID intValue = env->GetMethodID(intClass, "intValue", "()I");
    jint value = env->CallIntMethod(intObj, intValue);
    std::cout << "stuId:" << value << std::endl;


    jfieldID fileName = env->GetFieldID(jcs, "name", "Ljava/lang/String;");
    jstring classStr = (jstring) env->GetObjectField(obj, fileName);
    const char *cstr = env->GetStringUTFChars(classStr, 0);
    std::cout << "cstr:" << cstr << std::endl;
    return value;
}

使用的是cmake构建的话,那么就直接在CMakeLists.txt 中添加依赖就可以加上jni 依赖

cmake_minimum_required(VERSION 3.27)
project(testDDL2)

set(CMAKE_CXX_STANDARD 17)

find_package(JNI REQUIRED)

include_directories(${JNI_INCLUDE_DIRS})


add_library(testDDL2 SHARED
        JavaWithCppApplication.cpp
        )

# 链接 JNI 库
target_link_libraries(testDDL2 ${JNI_LIBRARIES})

cmke打包构建使用

在clion中点击构建,就可以打包产生我们需要的ddl文件了
在

java调用C++执行

如果你使用的是clion默认安装的c++的话,需要将clion默认安装的c++执行环境配置到系统环境变量,保证在命令行执行g++能够成功执行,我的是在 D:\software\JetBrains\CLion 2023.3.1\bin\mingw\bin 需要将这个路径配置在环境path下,否则java调用c++的时候就会出现ddl链接不到等问题,以及不可用等。配置好环境变量后需要重新启动下idea,否则环境变量还是加载不到,如果还是没生效就重启电脑。(我这里win11就是配置了重启才生效的)
如下成功调用

在这里插入图片描述

linux环境下产生CPP的so包

保证linux主机上安装有java的linux版本以及C++,cmake
将本地的项目整个上传到linux环境,到项目路径下,我这里是testDDL2,

cd  /home/chw/Documents/jni_test/testDDL2
mkdir build
cd build
cmake ..
make

构建完了之后再生成so文件 /home/chw/Documents/jni_test/testDDL2/build/libtestDDL2.so

如果爆出cmake版本不匹配就把CMakeLists.txt 里面的 cmake_minimum_required(VERSION 3.27) 版本调整一下,降低或者升高匹配一下安装的cmake版本。
如果还爆出某些依赖包找不到的问题,报错Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2),详细报错如下:

CMake Error at /usr/local/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2)
Call Stack (most recent call first):
  /usr/local/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  /usr/local/share/cmake-3.23/Modules/FindJNI.cmake:382 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:20 (find_package)

就加一下下面这里配置在CMakeLists.txt

# JAVA_INCLUDE_PATH为jni.h所在路径,一般在jdk目录下的include中
set(JAVA_INCLUDE_PATH /home/chw/software/jdk1.8.0_211/include)
# JAVA_INCLUDE_PATH2为jni_md.h所在路径,一般在jdk目录下的include/linux中
set(JAVA_INCLUDE_PATH2 /home/chw/software/jdk1.8.0_211/include/linux)
set(JAVA_AWT_INCLUDE_PATH /home/chw/software/jdk1.8.0_211/include)
set(JAVA_AWT_LIBRARY /home/chw/software/jdk1.8.0_211/lib)
set(JAVA_JVM_LIBRARY /home/chw/software/jdk1.8.0_211/lib)

在java中引入对应的so包就可以执行了
在这里插入图片描述

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

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

相关文章

【JavaScript】数组 ③ ( JavaScript 数组长度 | 修改数组长度 | 数组案例 )

文章目录 一、JavaScript 数组长度1、数组长度2、修改数组长度 二、数组案例1、求数组元素平均值2、求数组元素最大值 一、JavaScript 数组长度 1、数组长度 在 JavaScript 中 , 数组长度 可以通过 数组变量的 length 属性 获取 , 该属性 返回 数组中的元素数量 , 也就是 数组长…

软件速成书:一夜成神的传说,还是现实的泡影?

嗨&#xff0c;各位小伙伴&#xff01; &#x1f431;‍&#x1f4bb; 我是【行走的程序喵】&#xff01;一个兼具Web前端和Java后端技能的技术宅&#xff01; &#x1f31f; 我的博客上分享最新的Web前端和Java后端技术文章&#xff0c;从基础入门到进阶应用&#xff0c;应有…

Linux系统----------探索mysql数据库MHA高可用

目录 一、MHA概述 1.1 什么是 MHA 1.2MHA 的组成 1.2.1MHA Node&#xff08;数据节点&#xff09; 1.2.2MHA Manager&#xff08;管理节点&#xff09; 1.3MHA 的特点 1.4MHA工作原理 1.5数据同步的方式 1.5.1同步复制 1.5.2异步复制 1.5.3半同步复制 二、搭建 MySQ…

夜神模拟器录制脚本录制键盘操作方法

很多用户们在使用夜神模拟器的时候&#xff0c;有个操作助手的功能非常的好用&#xff0c;用户们在录制自己的操作以后&#xff0c;就能够进行全自动的操作等&#xff0c;使用起来还是非常方便的&#xff0c;想要知道的用户们快来查看详细的教程吧~ 夜神模拟器录制脚本怎样录制…

5-规范设计(下):commit信息风格迥异、难以阅读,如何规范?

我们在做代码开发时&#xff0c;经常需要提交代码&#xff0c;提交代码时需要填写 Commit Message&#xff08;提交说明&#xff09;&#xff0c;否则就不允许提交。 所以在 Go 项目开发时&#xff0c;一个好的 Commit Message 至关重要&#xff1a; 可以使自己或者其他开发人…

3.26学习总结java初步实现学生管理系统

(该项目通过视频讲解过程中完成,其中将一些操作进行了修改和完善,其目的是为了巩固前面学习java的一些用法,熟悉写项目的过程) 一.项目要求 学生类: 属性:id、姓名、年龄、家庭住址 添加功能: 键盘录入每一个学生信息并添加&#xff0c;需要满足以下要求: ID唯一 删除功能…

Qt源码调试步骤记录

1.源码&#xff1a; 两种方式&#xff0c;要么安装qt时选择source&#xff0c;要么从官网下载源码&#xff0c;然后在qt creator中设置路径。二选一即可。我选的第二种。 1.1.第一种&#xff0c;安装时选择source&#xff1a; 1.2.第二种&#xff0c;下载源码设置路径&#x…

Linux中安装JDK17.X

1、总体概述&#xff1f; 该操作方式适合centos或red hat环境 2.1、在线下载JDK安装包&#xff1f; 通过wget命令下载JDK17.X包 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz 如果提示&#xff1a;没有wget命令就安装wget yum install w…

Qt 富文本处理 (字体颜色大小加粗等)

Qt中支持HTML的控件有textEdit 、label 、textBrowser 。 接口&#xff1a;setHtml("Qt"); toHtml(). 文本样式设置 : 可分字设置 &#xff0c;主要使用QTextCharFormat类进行文本样式设置。 示例&#xff1a; QTextCharFormat fmt; //粗体 fmt.setFontWeight…

wps没保存关闭了恢复数据教程

有时候我们因为电脑问题会忘记保存就关闭wps导致数据丢失&#xff0c;不知道wps没保存关闭了怎么恢复数据&#xff0c;其实数据是无法恢复的。 wps没保存关闭了怎么恢复数据 1、wps没有数据恢复功能&#xff0c;不过可以开启自动备份。 2、我们可以先点击wps左上角的“文件”…

Vtk裁剪功能之平面裁剪vtkClipClosedSurface(vtk小记)

1.原理分析 对你的三维图形&#xff0c;使用一个平面切下去&#xff0c;然后保留一半。 确定一个平面&#xff1a;使用法向量和一个三维坐标点可以确定一个平面 原始图像 切一刀 切两刀&#xff0c;又一半 切三刀&#xff0c;又一半 源代码 #include <vtkActor.h> #i…

Linux 学习之路 -- 工具篇 -- gcc / g++

在 Linux 系统中&#xff0c;gcc 和 g 是两个常用的编译工具&#xff0c;分别用于编译 C 和 C 代码。下面我将介绍gcc、g的一些基本用法 目录 一、简单的认识 二、简单了解一下编译的过程 <1> 预处理阶段 <2>编译 <3>汇编 <4>链接…

SQLite数据库成为内存中数据库(三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; 下一篇&#xff1a;SQLite中的原子提交&#xff08;四) ​​ SQLite数据库通常存储在单个普通磁盘中文件。但是&#xff0c;在某些情况下&#xff0c;数据库可能…

python爬虫基础------函数

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

打工人神器! Raccoon 代码小浣熊

继这三个之后&#xff0c;今天又来了一个 [ Raccoon代码小浣熊 ] 核心精要与产品特点 全面支持多种编程语言和IDE&#xff1a;「代码小浣熊」支持超过90种主流编程语言&#xff0c;包括但不限于Python、Java、JavaScript、C、Go和SQL等。同时&#xff0c;它集成了市面上主流的…

电脑换屏总结——关于我把电脑砸了这件事!

大家好&#xff0c;我是工程师看海&#xff0c;很高兴和各位一起分享我的原创文章&#xff0c;喜欢和支持我的工程师&#xff0c;一定记得给我点赞、收藏、分享哟。 加微信[chunhou0820]与作者进群沟通交流。 【淘宝】https://m.tb.cn/h.5PAjLi7?tkvmMLW43KO7q CZ3457 「运放秘…

【ENSP】交换机和交换机之间实现静态路由

1.概念 三层交换机只能在Vlanif逻辑口配置iP地址 2.实现方法 交换机允许对应vlan通行&#xff0c;配置vlanif的ip地址&#xff0c;做静态路由 3.静态路由配置方法 ip route-static 目的网段 子网掩码 下一跳设备 LSW1三层交换机配置 u t m sys vlan batch 10 20 …

一文彻底搞懂并发容器

文章目录 1. 什么是并发容器2. 并发容器的分类 1. 什么是并发容器 并发容器是一种用于多线程环境的数据结构&#xff0c;它们能够有效地处理并发访问和修改的问题。在多线程应用程序中&#xff0c;多个线程可能会同时访问和修改共享的数据结构&#xff0c;这可能会导致数据不一…

npm卸载不掉的解决方案

不管怎么重装重启都报错 真服了&#xff0c;npm卸载不掉绝对是有缓存存在&#xff0c;用where npm查到d盘 实际上根本不在这个地方&#xff0c;这个是我安装的6.14.12版本的npm的地方&#xff0c;我说我怎么怎么重装怎么导包都不行呢&#xff0c;偷偷隐藏在这个目录里面&#…

vue3路由代码示例

路由简单分三步吧 第一定义路由&#xff1a; 包括访问地址&#xff0c;对应组件 第二使用&#xff1a;在index.html中使用它 下面是代码示例&#xff1a; components/Person.vue <template><router-link to"/test/hello">跳转</router-link>&…