Java的JNI机制-简单实践

Java的JNI机制

Java还有一个JNI机制,它的全称:Java Native Interface,即Java本地接口。它允许在Java虚拟机内运行的Java代码与其他编程语言(如C/C++和汇编语言)编写的程序和库进行交互(在Android开发中用得比较多)

简单举例:我们现在想要让C++语言程序帮助我们的Java程序实现a+b的运算,首先我们需要创建一个本地方法:

package com.test;

public class Main {
    
    public static void main(String[] args) {
        System.out.println(sum(1,2));
    }
    //native 是本地方法关键字,无需在Java中实现本方法
    public static native int sum(int a,int b);
}

创建好后,接着点击构建按钮,会出现一个out文件夹,也就是生成的class文件在其中

接着我们直接生成对应的C头文件:

(注意,这条指令基于jdk1.8实现,jdk版本过高 请使用javac -h指令)

javah -classpath out/production/pro02 -d ./jni com.test.Main

生成的头文件位于jni文件夹下:

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

#ifndef _Included_com_test_Main
#define _Included_com_test_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_Main
 * Method:    sum
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_com_test_Main_sum
    //这里的两个jint就是传入的a,b两个参数
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

接着我们在CLion中新建一个C++项目,引入刚刚生成的头文件并导入jni相关头文件(在JDK文件夹中)

首先修改CMake文件:

cmake_minimum_required(VERSION 3.20)
project(pro02)

#和使用的jdk的路径有关
include_directories(E:/Users/19318/.jdks/corretto-1.8.0_322-1/include)
include_directories(E:/Users/19318/.jdks/corretto-1.8.0_322-1/include/win32)
include_directories(E:/Users/19318/.jdks/corretto-1.8.0_322-1/include/win32/bridge)

set(CMAKE_CXX_STANDARD 14)

#add_executable:生成一个可执行文件 不添加则无法再clion中运行
add_executable(pro02 com_test_Main.cpp com_test_Main.h)
#add_library:生成一个库
#sum:是生成共享库的名字,前面会自动加上lib前缀,如这里windows生成的是 libsum.dll
#SHARED:库的类型为动态,windows上生成.dll,而STATIC 则是生成静态库,windows生成.a文件
add_library(sum SHARED com_test_Main.cpp)

再将jni下的头文件复制到c++项目下:

认识一下引用类型对照表:

接下来可以开始编写程序了:

#include <jni.h>
#include "com_test_Main.h"


JNIEXPORT jint JNICALL Java_com_test_Main_sum
  (JNIEnv *, jclass, jint a, jint b)
{
  return a+b;
}

接着我们就可以将cpp编译为动态链接库,在Windows下应该生成.dll文件

直接运行项目,我们可以在cmake-build-debug文件夹下找到生成的dll文件

注意这里运行时会报错undefined reference to 'WinMain',因为我们的项目没有main函数,但报错并不影响dll文件的生成和使用。

将生成的dll文件加载到Java程序中,运行即可得到结果。

public class Main {
    static {
        //输入dll文件的路径
        System.load("D:\\C++\\pro02\\cmake-build-debug\\libsum.dll");
    }
    public static void main(String[] args) {
        System.out.println(sum(1,2));
    }

    public static native int sum(int a,int b);
}

猜你喜欢

转载自blog.csdn.net/m0_51561690/article/details/128687012
今日推荐