java调用c++,使用clion进行JNI开发,ddl包生成以及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包就可以执行了
在这里插入图片描述

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值