一,项目前提:
我们目前是想实现一个人脸识别考勤的项目,而厂商给我们所提供的是c++封装好的jdk 。为了方便跟我们的Java平台对接,因此需要一些手段将C++项目融入到我们的Java 平台当中。我们最终选用JNA来对c++ sdk 来进行封装。项目使用jdk(1.8.0_201)、 idea(2018.3.3)、jna版本(3.4.0)
ps:小编在jna版本上曾经踩过坑,发现使用的jna(4.2.2), 运行代码始终不成功,类继承 Structure 类的时候 。重写
getFieldOrder() 方法写法也很繁琐, 后来发现很多人都用的是3.4.0版本的JNA 。并且这个版本的jna可以不用非要去重写getFieldOrder()这个方法。后面我们会提到为什么可以不用重写这个方法了。
二,项目方案选择:
JNI:是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
1,JNI
1,jni的简单应用
2,jni在java中的应用(jdk1.1 之后 才加入了JNI的概念:在 IO 、net 、lang包下面偏多)。下面我们去JDK中IO中去看下这些本地方法吧。
/**
* Reads a subarray as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private native int readBytes(byte b[], int off, int len) throws IOException;
这个方法是出现在 FileInputStream 这个类中。
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes. This method blocks until some input
* is available.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
然后这个 readBytes(b, off, len) 方法就会调用上面的这个本地Native 方法。至于这些方法的作用,自己看一看应该也能看得懂,但至于Native内部怎么实现,也不必太过追究。
2,JNA的使用
1,JNA相比JNI有什么优势呢?
下面来看一看JNA的维基百科解释
PS:关键点在于:JNA的设计旨在以最少的努力以自然的方式提供原生访问。它能支持macOS,Microsoft Windows,FreeBSD / OpenBSD,