一、JNI
(一)功能
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)
1. 调用 API
调用 API 允许软件供应商将 Java VM 加载到任意本机应用程序中。
(1)库和版本管理
当本机库加载时(例如,通过System.loadLibrary
), VM调用JNI_OnLoad
。JNI_OnLoad
必须返回本机库所需的JNI版本。
为了使用任何新的JNI函数,本机库必须导出返回JNI_VERSION_1_2
的JNI_OnLoad
函数。如果本机库没有导出JNI_OnLoad
函数,虚拟机将假定库只需要JNI版本JNI_VERSION_1_1
。如果虚拟机不能识别JNI_OnLoad返回的版本号,则无法加载本机库。
(2)Getenv
样例
jint GetEnv(JavaVM *vm, void **env, jint version);
参数
JavaVM *vm
:将从中检索接口的虚拟机实例。
void **env
:指向当前线程的 JNI 接口指针将放置的位置的指针。
jint version
: 请求的 Jni 版本。
返回
如果当前线程没有绑定到虚拟机,将*env
设置为NULL
,并返回JNI_EDETACHED
。如果指定的版本不受支持,将*env
设置为NULL
,并返回JNI_EVERSION
。否则,将*env
设置为适当的接口,并返回JNI_OK
。
(二) 测试环境
win10 19042.746
idea 3.1
clion 3.1
c++ 98
java 8
(三)关于JNI的简单使用
1. 编写java代码
package com.zjh.jnitest;
/**
* @author 98283
*/
public class JNIDemo {
public native void testHello();
public static void main(String[] args) {
JNIDemo jniDemo = new JNIDemo();
jniDemo.testHello();
}
}
2. 生成.h文件
进入根目录
根目录是啥看package就好了
执行javah -classpath . -jni com.zjh.jnitest.JNIDemo
然后可以在根目录得到一个
com_zjh_jnitest_JNIDemo.h文件
函数说明
javah:从 Java 类生成 C 标头和源文件
-classpath path:指定从中加载引导类的路径 path . 你的路径
-jni:创建函数原型的输出文件
3. 编写C++文件
#include "JNI.h"
#include <iostream>
JNIEXPORT void JNICALL Java_com_zjh_jnitest_JNIDemo_testHello
(JNIEnv *, jobject){
std::cout << "Hello, World!" << std::endl;
}
函数说明
···JNIEXPORT void JNICALL :
就这个测试来讲就是一个接口
···Java_com_zjh_jnitest_JNIDemo_testHello:
动态链接器根据条目的名称解析条目。本机方法名称从以下组件串联:
·前缀Java_
·完全限定类名下划线 ("_") 分隔符
JNIEnv:JNI 接口指针
jobject:有待补充参数因本机方法是静态的还是非静态的而异。非静态本机方法的第二个参数是对对象的引用。静态本机方法的第二个参数是引用其 Java 类。
可能出现的错误
(A)“JNI.h"没找到:在CMakeLists.txt中添加如下语句
include_directories("F:/app/jdk-1.8.0_275/include")
include_directories("F:/app/jdk-1.8.0_275/include/win32")
4. 编译生成dll文件
5. 重写java代码
package com.zjh.jnitest;
/**
* @author 98283
*/