当前位置:网站首页>JNI study
JNI study
2022-08-07 16:57:00 【The vast number of rookies】
目标
1、 Java通过JNI调用C++动态链接库Demo实现全过程,Add decoupling,
包括一个DllA dynamic link library calls the contents of another dynamic link library
2、Implement a pass parameter,and get the return valueJNI项目版本
1、创建C++环境 – 目标功能
1.1 选择Dll模板

1.2 创建第一个dll项目

1.3 新建一个头文件 WindowHidUsb.h 和一个WindowHidUsb.cpp

1.4 修改visual studio dll类型
项目-》属性-》配置管理器-》Win32 改为x64
2、创建一个Java环境
2.1 创建类
package com.mtk.ups.agent.api.usb;
/** * Created with IntelliJ IDEA. * 测试JNI * @author 广大菜鸟 * @since 2022/7/13 22:08 * E-mail: [email protected] */
public class MtkUsbJNI {
/** * 使用dll返回设备数量 * @return 设备数量 */
native int scanDevice();
}
2.2 用JNI将C++The code header files are born inJavaunder the project source folder
javah -jni -encoding utf-8 com.mtk.ups.agent.api.usb.MtkUsbJNI

3、创建c++环境 – bridge function
创建MtkHidUsbBridge项目
3.1 导入JNI生成.h文件
3.2 创建MtkHidUsbBridge.cpp文件
3.3 关联JNIThe directory corresponding to the generated header file and othersJNI头文件目录,添加到jdk下面
右键 ->属性


Useless words above,则配置所有:右键工程 根目录(https://so.csdn.net/so/search?q=根目录&spm=1001.2101.3001.7020)→ 属性 → 最上面修改为“所有配置”、“所有平台”
添加头文件目录:右键工程根目录→ 属性 → C/C++ → 常规 → 附加包含目录,添加include目录.



运行MtkHidUsbBridge.cpp,生成dll.将dll加入idea环境依赖:project structure -> Librarys -> +号
(后面生成dllall in this way)


4、Test the bridge withjava
MtkUsbJNI.java
package com.mtk.ups.agent.api.usb;
/** * Created with IntelliJ IDEA. * 测试JNI * @author 广大菜鸟 * @since 2022/7/13 22:08 * E-mail: [email protected] */
class MtkUsbJNI {
/** * 使用dll返回设备数量 * @return 设备数量 */
native int scanDevice();
}
构造MtkUsb单例调用MtkUsbJNI的native方法
package com.mtk.ups.agent.api.usb;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/13 23:53 * E-mail: [email protected] */
public class MtkUsb {
private static final MtkUsb mtkUsb = new MtkUsb();
private static final MtkUsbJNI mtkUsbJni = new MtkUsbJNI();
private MtkUsb(){
}
public static MtkUsb getInstance(){
return mtkUsb;
}
public int scanDevice(){
return mtkUsbJni.scanDevice();
}
}
构造测试类
package com.mtk.ups.agent.api;
import com.mtk.ups.agent.api.usb.MtkUsb;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/13 23:51 * E-mail: [email protected] */
public class MtkHidUsbTest {
public static void main(String[] args) {
System.loadLibrary("MtkHidUsbBridge");
System.out.println("Device count = "+ MtkUsb.getInstance().scanDevice());
}
}
5、修改目标dlland bridgedll,实现解耦
5.1 在目标c++项目内
pch.h
// pch.h: 这是预编译标头文件.
// 下方列出的文件仅编译一次,提高了将来生成的生成性能.
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能.
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译.
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效.
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
#define API_DLL __declspec(dllexport)
#endif //PCH_H
WindowHidUsb.h
#pragma once
#include "pch.h"
API_DLL int scanDevice();
WindowHidUsb.cpp
#include"WindowHidUsb.h"
#include "pch.h"
API_DLL int scanDevice() {
return 2;
}
重新生成项目,将Release的.dll文件拷贝到java的src目录下
5.2 在Java项目内,增加dll导入语句
package com.mtk.ups.agent.api;
import com.mtk.ups.agent.api.usb.MtkUsb;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/13 23:51 * E-mail: [email protected] */
public class MtkHidUsbTest {
public static void main(String[] args) {
System.loadLibrary("MtkHidUsb");
System.loadLibrary("MtkHidUsbBridge");
System.out.println("Device count = "+ MtkUsb.getInstance().scanDevice());
}
}
5.3 桥梁项目
5.3.1 Copy the target project'sWindowHidUsb.hfile to the bridge project,并修改内容
#pragma once
#include "pch.h"
#if defined(WIN32)
#if defined(Release)
#pragma comment(lib, "C:/Users/Lenovo/Desktop/JNIDemo/MtkHidUsb/x64/Release/MtkHidUsb.lib")
#pragma message("Automatically linking debug with MtkHidUsb.lib")
#else
#pragma comment(lib, "C:/Users/Lenovo/Desktop/JNIDemo/MtkHidUsb/x64/Debug/MtkHidUsb.lib")
#pragma message("Automatically linking debug with MtkHidUsb.lib")
#endif
#endif
int scanDevice();
5.3.2 修改 WindowHidUsbBridge.cpp
#include "pch.h"
#include "com_mtk_ups_agent_api_usb_MtkUsbJNI.h"
#include "WindowHidUsb.h"
JNIEXPORT jint JNICALL Java_com_mtk_ups_agent_api_usb_MtkUsbJNI_scanDevice
(JNIEnv*, jobject) {
//Get it from the underlying library
return scanDevice();
}
5.3.3 生成新的WindowHidUsbBridge.dll文件,拷贝到java环境,加入依赖
6.进阶–传值
6.1 创建java项目
消息结构体
package com.demo.bean;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/14 23:12 * E-mail: [email protected] */
public class ApiResult {
private int result;
private String description;
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Native类
package com.demo.api;
import com.demo.bean.ApiResult;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/14 23:14 * E-mail: [email protected] */
public class NativeApiJni {
native ApiResult getApiResult(int index);
}
编写单例模式 NativeApi
package com.demo.api;
import com.demo.bean.ApiResult;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/14 23:17 * E-mail: [email protected] */
public class NativeApi {
private final NativeApiJni jni = new NativeApiJni();
private static final NativeApi api = new NativeApi();
private NativeApi(){
}
public static NativeApi getInstance(){
return api;
}
public ApiResult getApiResult(int index){
return jni.getApiResult(index);
}
}
编写测试类
Test.java
package com.demo;
import com.demo.api.NativeApi;
import com.demo.bean.ApiResult;
/** * Created with IntelliJ IDEA. * * @author 广大菜鸟 * @since 2022/7/14 23:16 * E-mail: [email protected] */
public class Test {
public static void main(String[] args) {
System.loadLibrary("ApiNativeDll");
ApiResult result = NativeApi.getInstance().getApiResult(0);
System.out.println(result);
result = NativeApi.getInstance().getApiResult(1);
System.out.println(result);
}
}
6.2 创建C++dll项目
ApiNativeDll.cpp
#include"pch.h"
#include"com_demo_api_NativeApiJni.h"
#include"ApiNativeDll.h" // 为空
JNIEXPORT jobject JNICALL Java_com_demo_api_NativeApiJni_getApiResult(JNIEnv* env, jobject, jint jIndex) {
//获取Java实例
jclass objectC1ass = env->FindClass("com/demo/bean/ApiResult");
//Get member variable a constructor
jmethodID objectC1assInitID = env->GetMethodID(objectC1ass, "<init>", "()V");
//创建Java对象
jobject objectNewApiResult = env->NewObject(objectC1ass, objectC1assInitID);
//获取属性
jfieldID resultField = env->GetFieldID(objectC1ass, "result", "I");
jfieldID descriptionField = env->GetFieldID(objectC1ass, "description", "Ljava/lang/String;");
env->SetIntField(objectNewApiResult, resultField, jIndex);
env->SetObjectField(objectNewApiResult, descriptionField, env->NewStringUTF(jIndex > 0 ? "Failure" : "Success"));
//或者 调用方法: (*env)->CallVoidMethod(env, obj, mid, depth);
return objectNewApiResult;
}
The rest of the operations are the same as before,结果是

7.参考学习资料
- 搭建基本jni项目
https://www.bilibili.com/video/BV1gq4y1x7Ae - 传对象
https://www.bilibili.com/video/BV1444y1G76L - java和c++Corresponding type signature
https://blog.csdn.net/u013718730/article/details/118067145
补充资料:
Javaeach type and method in ,Both correspond to a unique string,This is the signature
| Java类型 | 签名 |
|---|---|
| boolean | Z |
| byte | B |
| char | C |
| short | S |
| int | I |
| long | L |
| float | F |
| double | D |
| Object | L+包名+分号 |
| [] | [+类型签名 |
| [][] | [[+类型签名 |
| 方法 | (参数签名)+返回值签名 |
对象类型 An example of a signature is as follows
| Java类型 | 签名 |
|---|---|
| String | Ljava/lang/String; |
| Object | Ljava/lang/Object; |
| String[] | [Ljava/lang/String; |
| int func(int i, Object object) | (ILjava/lang/Object;)I |
边栏推荐
猜你喜欢
随机推荐
R语言使用scale函数将向量数据或者dataframe指定数据列转换为Z分数(z-Scores、转化为规范化数据)
系统设计题面试八股文背诵版
做项目,你需要。。。【持续更新】
深度解析期权现货合约交易所系统开发说明分析
利用联合索引优化filesoert
Analysis of UVC device enumeration based on STM32
嵌入式系统驱动初级【10】——中断处理下_下半部机制
嵌入式系统驱动高级【1】——设备模型
JVM high frequency interview questions PDF version
传统伪影去除方案
JVM高频面试题PDF版
易趋受邀参加第十届中国核电信息技术高峰论坛
win7系统垃圾怎么清理_win7系统垃圾清理的方法
2022-08-06 第四小组 修身课 学习笔记(every day)
台式机怎么连接路由器 台式机如何连接路由器上网图解
基于FTP协议的文件上传与下载
戴尔灵越15pro配置 戴尔灵越15pro值得买吗
美团一面面经及详细答案
2.10 - 存储管理 2.11 - 页式存储 2.12 - 段式存储 2.13 - 段页式存储
R语言ggplot2可视化:使用patchwork包将多个ggplot2可视化结果组合起来、使用plot_spacer函数在组合结果图像中的指定位置加入空白区域(不包含任何内容,纯粹空白图)









