文档章节

JNA, Java Native开发利器

彭苏云
 彭苏云
发布于 2013/04/16 10:03
字数 1004
阅读 1392
收藏 13

下面的文章由转载而来,java与c++的调用基本思路是这样子,但是结合我的使用经验,在使用jna和jnative的时候需要考虑到jdk的版本,jnative跟jdk1.4的结合可能会有点问题,因为我之前选的是jnative,而我们的jdk版本是1.4,我们下载的jnative jar不支持1.4版本,这样才换了jna,庆幸jna支持jdk1.4,特作此说明。

--------------------------------------------------------------------------------------------------

简单的来说,这篇文章就是介绍一个十分好用的Java Native开发工具, JNA。 在Java编程中,大部分时间都不需要理会JNI,但是当你需要调用一个本地的C/C++库的时候,你就不得不考虑如果在Java中调用C库中的接口(dll, so)。这样的情况有很多,比如当你需要访问一个硬件时,而硬件厂商只提供C语言写的驱动和库文件。 刚开始,或许像我一样,大部分人知道Java有一个叫JNI的东西可以做到这一点,还不坏不是么,至少可以实现它。但是JNI的编写相当复杂和拙劣,关键的一点是需要编写C代码,要知道这对于相当一部分Java程序员来说可不是一个容易的事情。除了你要精通C语言,还要熟悉JNI的知识,包括C的数据类型如何对应到JNI的C数据类型,又如何对应到Java的数据类型,还有很多其他的细节需要注意,比如垃圾回收的问题,还有结构体数据类型对应问题,跨平台问题等等都足以把你搞得头大。很多情况下,只不过是为了调用一个第三方库,不得不再造出自己的一个库,不得不编写JNI代码和本地代码。我为什么不能直接调用本地库代码? 直到有那么一天,某个人告诉你有个叫JNA的东西,就是专门用来解决这个问题的。像下面这个例子这么简单。  

package com.sun.jna.examples;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/** Simple example of JNA interface mapping and usage. */
public class HelloWorld {

// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.

public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
CLibrary.class);

void printf(String format, Object... args);
}

public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, World\n");
for (int i=0;i < args.length;i++) {
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
}
}
}
使用JNA,你甚至不需要很多的文档,只要拿到第三方库的头文件,比如third.h,根据里面的函数定义直接生成Java的代码,几分钟就可以搞定。Java和本地C库的映射,可以根据头文件直接生成,甚至不用开发人员手动编写对应关系。要用哪几个函数,就在Java接口中添加哪几个函数。你可以按照自己想要的方式加载本地库(如果你曾被JNI下面System.loadLibrary那捉摸不定的java.library.path搞得生不如死),JNA还可以做到C结构体和Java类的映射,如果你需要在Java中,向本地方法传递结构体,这就会很有用:  

public static class SYSTEMTIME extends Structure {
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}

void GetSystemTime(SYSTEMTIME result);

相比较与JNI来说,JNA也有它的缺点,其实JNA是建立与JNI的基础之上的,所以如果对性能要求特别高,那么多花点时间在JNI上面也许是值得的。另外,JNA在Java调用底层C库的时候特别方便,但是反过来,如果想要从C里面调用Java,JNA可能会遇到不小的麻烦,这时候你也许需要转回到JNI. 如果你还对Java的Native开发心有余悸,希望这篇介绍的JNA的文章可以帮助你跨越JNI开发的这道鸿沟:)

本文转载自:http://hackfisher.info/blog/2011/06/jna-java-native/

共有 人打赏支持
彭苏云
粉丝 42
博文 204
码字总数 54255
作品 0
广州
高级程序员
私信 提问
加载中

评论(4)

彭苏云
彭苏云
这个问题有点复杂,不会了!
茱萸
茱萸
JNA遇到复杂的C程序不知道怎么破,例如LINUX下调用SO,这个SO又有一些方法调用的是.a的静态类库。这种情况下JNA无法加载这个方法。这种情况怎么破
彭苏云
彭苏云
嘿嘿,有人评论了!
chape
chape
mark
JNI --&-- JNA

最近写SDK,解释下什么是SDK,SDK一般是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。开发SDK时使用JNI去调用SO或DLL是一件多么痛苦的...

燚想天开
2012/12/18
0
0
JNA调用DLL函数遇到的几个问题

最近一个JSP项目需要用到分词模块,而分词模块实用C++写成的DLL库。于是上网搜各种方法,最后选择了JNA作为JSP调用DLL的工具。 JNA(Java Native Access )提供一组Java工具类用于在运行期动...

雷霄骅
2013/09/30
0
0
使用JNA替代JNI调用本地方法

JNA全称是Java Native Access,是Sun推出的一种调用本地方法技术,比起它的同门师兄JNI,JNA大大简化了调用本地方法的过程,使用也比较方便, JNA是在JNI的基础上完善的,用青出于蓝而胜于蓝来形容...

thinkyoung
2014/10/25
0
0
Cubieboard 3(cubietruck) 安装Jenkins

jenkins 安装目录是 /var/lib/jenkins 启动/关闭 sudo /etc/init.d/jenkins start sudo /etc/init.d/jenkins stop log 路径 为 /var/log/jenkins/jenkins.log jenkins 修改 默认 访问端口 在......

乾坤摄
2014/05/07
0
0
已有C++ lib的so文件 .h文件, 怎么在linux下 以 java Demo 运行 并调用C++代码。 JNA方式。

我是按照。https://www.cnblogs.com/lanxuezaipiao/p/3635556.html 上的做的。 本地windows没有C++ 的dll文件,测试不了,想写个简单的类,看看能不能调用C++ 的代码。 下载了第三方的JNA-4...

今天天气不错啊
10/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 快捷键

快捷键图标。 官方的下载地址为:https://atlassianblog.wpengine.com/wp-content/uploads/2018/01/keyboard-shortcuts-infographics.pdf...

honeymose
57分钟前
2
0
Apache限定目录解析PHP,限制user_agent,PHP相关的配置

Apache限定目录解析PHP 配置前访问upload/index.php [root@test-a ~]# curl -x192.168.77.139:80 'www.test.com/upload/index.php'This is upload diretory 配置,/usr/local/apache2.4/......

野雪球
今天
3
0
java.util.Concurrent.Exchanger源码

类图 源码: package java.util.concurrent;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicReference;import java.util.concurrent......

狼王黄师傅
今天
6
0
Kubernetes里的secret最基本的用法

Secret解决了密码、token、密钥等敏感数据的配置问题,使用Secret可以避免把这些敏感数据以明文的形式暴露到镜像或者Pod Spec中。 Secret可以以Volume或者环境变量的方式使用。 使用如下命令...

JerryWang_SAP
昨天
5
0
2018-11-20学习笔记

1. python数据类型: 给变量赋值什么样的值,变量就是什么样的类型 给变量赋值整数,变量就是整数类型 给变量赋值字符串,变量就是字符串类型 123 和“123”一样吗? 在python中 单引号 与双...

laoba
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部