• Java通过JNI技术调用C++动态链接库的helloword测试


    JNI调用原理

    原理就不细说了,其实就是写个库给Java调,可以百度一下Java JNI,下面是HelloWorld代码测试

    编写一个本地测试类

    package com.my.study.cpp_jni;
    
    /**
     * 测试Java调用C++库
     * 

    使用命令javac -h . NativeTest.java自动生成C头文件

    *

    到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来

    *

    实现cpp文件

    *

    编译

    *

    导入

    *

    配置cpp库文件

    *

    System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.so");

    * */
    public class NativeTest { static { /* // 设置java.library.path路径 System.setProperty("java.library.path", "/path/to/library"); // 通过System.loadLibrary()加载库文件 System.loadLibrary("mylibrary"); */ System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.dll"); } private native void print(); public static void main(String[] args) { new NativeTest().print(); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    java文件格式说明

    使用JavaC命令生成C语言的头文件.h文件

    用命令javac -h . NativeTest.java自动生成C头文件

    javac -h . NativeTest.java
    
    • 1

    生成文件com_my_study_cpp_jni_NativeTest.h:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include "jni.h"
    /* Header for class com_my_study_cpp_jni_NativeTest */
    
    #ifndef _Included_com_my_study_cpp_jni_NativeTest
    #define _Included_com_my_study_cpp_jni_NativeTest
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_my_study_cpp_jni_NativeTest
     * Method:    print
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    com_my_study_cpp_jni_NativeTest.h文件格式说明

    拷贝JDK include目录下的jni.h和win32/jni_md.h头文件到相同路径

    修改com_my_study_cpp_jni_NativeTest.h文件的#include 为#include "jni.h"引入方式,避免查找C/C++库
    在这里插入图片描述

    NativeTest.cpp实现C头文件函数

    #include
    #include "com_my_study_cpp_jni_NativeTest.h"
    
    
    using namespace std;
    JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print(JNIEnv *, jobject) {
      	cout << "Hello Word JNI" << endl;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    编译C++库文件

    编译C源代码并创建本地库

    // 编译C语言库
    // gcc -ID:\xxx\Java\Java8\jdk\include\ -ID:\xxx\Java\Java8\jdk\include\win32\ NativeTest.c -shared -o MyLibrary.so
    // 编译C++库
    // g++ -ID:\xxx\Java\Java8\jdk\include\ -ID:\xxx\Java\Java8\jdk\include\win32\ NativeTest.cpp -shared -o MyLibrary.so
    // gcc -I 表示将后面的目录表示为第n个头文件的目录

    执行测试,报错

    在这里插入图片描述

    解决错误问题,确认gcc、g++版本是32还是64位

    这里不如直接把vs装上测试,因为那个无法找到库文件的问题我弄了几个小时,这里不如直接装上vs,装好vs后几分钟就生成好dll库了
    我这里使用VS2022生成动态链接库,装好创建一个C++项目
    这里是刚才根据对应头文件和cpp实现文件创建的文件结构,文件都是上面的文件,把文件放到对应位置就行了
    在这里插入图片描述

    对了这里的pch.h预编译头去掉一下,因为用不到,要不然一直报错
    在这里插入图片描述

    使用vs生成动态链接库,把生成的代码放到D盘根目录,方便测试,修改一下Java测试代码,这里可以看到我这里使用g++指令生成的动态链接库比使用vs生成的动态链接库小,说明使用指令生成的动态链接库还差了什么东西在里面,我对C++也不熟悉,所以这里使用vs生成了
    在这里插入图片描述

    /**
     * 测试Java调用C++库
     * 

    使用命令javac -h . NativeTest.java自动生成C头文件

    *

    到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来

    *

    实现cpp文件

    *

    编译

    *

    导入

    *

    配置cpp库文件

    *

    System.load("D:/xxx/java/com/my/study/cpp_jni/_013_Cpp_VS_Dynamic_Link_Lib.dll");

    *

    System.loadLibrary("_013_Cpp_VS_Dynamic_Link_Lib");//不加dll

    * Can't load IA 32-bit .dll on a AMD 64-bit platform:需要下载64位cpp编译器,不同cpu编译器不同 */
    public class NativeTest { static { System.load("D:/_013_Cpp_VS_Dynamic_Link_Lib.dll"); } private native void print(); public static void main(String[] args) { new NativeTest().print(); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    idea运行测试:
    在这里插入图片描述
    这里可以看到运行了C++编译打印的字符串Hello World JNI,成功了,撒花

    总结:

    1. 创建Java文件,函数用native标记
    2. 生成.h头文件
    3. 拷贝jni.h,jni_md.h文件,调整文件引用位置
    4. 实现头文件
    5. 生成动态链接库(这里使用VS)
    6. Java调用
  • 相关阅读:
    科研学习|研究方法——使用python强大的Statsmodel 执行假设检验和线性回归
    基于Java+SpringBoot+mybatis+vue的旅游管理系统详细设计
    Matlab论文插图绘制模板第67期—三角网格图(Trimesh)
    机器学习(三十四):可视化决策树的四个方法
    Xception学习笔记
    【C/C++笔试练习】常见进制转换、宏的定义和特点、sizeof与strlen、字符串函数、统计回文、连续最大和
    ClickHouse 原理解析之基础知识总结
    通讯网关软件018——利用CommGate X2MQTT实现MQTT访问OPC Server
    VS编译.cu文件源文件无法打开matrix.h和mex.h问题
    以太网_底层
  • 原文地址:https://blog.csdn.net/qq_27577113/article/details/134359978