Windows JNI 调试记录

19 篇文章 0 订阅
17 篇文章 0 订阅

一. 前言

       最近接到一个项目,由于我们公司做水控设备项目,买的挺好的,有一个客户需要做对需要我们设备接入他们的系统,于是需要我们提供二次开发接口,而且是Java 平台的,通过由于这个项目我编写的客户端是使用C# 编写的,并且都是所有接口都是集成到客户端中,因此没有预留给其他平台调用的接口。由于Java Web 不能直接操作硬件。因此,需要我提供Java 能调用的接口,Java能调用的接口并且可以直接操作硬件,只能是C/C++ 。于是,通过JNI Java可以间接操作我们公司的USB设备,于是写下这篇文件,记录JNI 编写的过程,防止下次忘记了,又需要重新学习。

二. 简介

2.1 什么是JNI

JNI(Java Native Interface)意为JAVA本地调用,它允许Java代码和其他语言写的代码进行交互相(一般为C/C++),简单的说,一种在Java虚拟机控制下执行代码的标准机制。

2.2 JNIEnv与JavaVM 

JNIEnv 概念 : 是一个线程相关的结构体, 该结构体代表了 Java 在本线程的运行环境 ; 

JNIEnv 与 JavaVM : 注意区分这两个概念; 
-- JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局只有一个;
-- JNIEnv : JavaVM 在线程中的代表, 每个线程都有一个, JNI 中可能有很多个 JNIEnv;

JNIEnv 作用 : 
-- 调用 Java 函数 : JNIEnv 代表 Java 运行环境, 可以使用 JNIEnv 调用 Java 中的代码;
-- 操作 Java 对象 : Java 对象传入 JNI 层就是 Jobject 对象, 需要使用 JNIEnv 来操作这个 Java 对象;

摘自《JNI 实战全面解析

2.3

详细关于JNI 相关可以查看大神文章,讲的非常好《JNI 实战全面解析

三. 开发环境

        (1) JDK v1.8    (2) Eclipse 2018-12 (4.10.0)   (3) Visual Studio 2015

四. JNI 相关代码编写

4.1 编写由Java native 类接口,通过javah 命令生成.h文件

java 类

package com.chen.jni;

public class JNIInterface
{
	//由java 调用c/c++ 接口打印信息
	public native void hellojni();
	
	//java 传递 byte 数据到C/C++ 中,并且修改
	public native void testByteArray(byte[] stream);
	
	static {
		System.loadLibrary("testjni");
	}
}

使用找到JNIInterface.java 文件,使用在Windows 控制台中javah -classpath . -jni com.chen.JNIInterface 生成对应.h 文件

如下图:

4.2 使用VS 创建DLL 工程,编写JNI 到x64动态库

4.2.1 新建Win32 控制台工程

4.2.2 选择DLL

4.2.3 将使用javah 生成的.h 文件拷贝到Win32 DLL 工程目录下

4.2.4 将.h 文件添加到工程上和jni.h 相关的文件也拷贝到工程目录下,并且添加到工程中将jni.h 和相关文件拷贝出来,是方便当工程移动到别的电脑照样可以直接编译。

 

4.2.5 编写同名.cpp 文件,并且实现接口

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "com_chen_jni_JNIInterface.h"

/*
 * Class:     com_chen_jni_JNIInterface
 * Method:    hellojni
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_chen_jni_JNIInterface_hellojni
(JNIEnv *env, jobject jobj)
{
	printf("helllo jni");
}

/*
 * Class:     com_chen_jni_JNIInterface
 * Method:    testByteArray
 * Signature: ([B)V
 */
JNIEXPORT void JNICALL Java_com_chen_jni_JNIInterface_testByteArray
(JNIEnv * env,  jobject jobj,  jbyteArray jByteArray)
{
	int ik = 0;
	unsigned char data[4] = { 0 };

	env->GetByteArrayRegion(jByteArray, 0, 4, (jbyte *)data);

	printf("java to c++ data\n");
	for (ik = 0; ik < 4; ik++)
	{
		printf("data[%d] = %.2X  ", ik, data[ik]);
		data[ik] = data[ik] + 1;
	}

	env->SetByteArrayRegion(jByteArray,  0, 4, (jbyte *)data);
}

 

 

4.2.6 在C/C++ 工程配置中,添加JNI 目录依赖

4.2.7 根据使用场景,配置工程编译为64位DLL 或者32 位DLL.

 

4.3 在Eclipse 中Java 通过JNI 调用C++

4.3.1 将生成的DLL 拷贝到java 工程目录下

 

4.3.2 配置工程,增加JNI 库支持

然后,就可以调用了。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值