文档章节

JNA, Java Native开发利器

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

下面的文章由转载而来,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/

共有 人打赏支持
彭苏云
粉丝 41
博文 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
JNA调用window api中的MessageBox

用JNA调用C/C++,很方便,写了个很简单的例子。 例子是使用Eclipse CDT + MinGW开发的: C代码,hello.c #include <windows.h> #include "stdio.h" void say(){ MessageBox (NULL, TEXT ("你......

penngo
2011/01/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JS三元运算示例

1. topFlag=topFlag ==0?1:0; 等于 if(topFlag=00){ topFlag=1; }else if(topFlag == 1){ topFlag=0; } 2. 5>3?alert('5大'):alert('3大'); 即 if(5>3){alert('5大')}else{alert('3大')}; 注......

森火
今天
0
0
利用Slf4j的MDC跟踪方法调用链

why? 一个web项目通常提供很多URL访问地址, 项目一般都是分层处理,例如Controller——>Service——>DAO。 如果想根据日志查看用户一次请求都走了哪些方法(多数是查错误)。 如果系统是多人...

杨春炼
今天
9
0
Maven介绍及安装

Maven介绍及安装 以下内容是本人早期学习时的笔记,可能比较详实繁琐,现在复习一下Maven,顺便将内容抛出来,供大家一起学习进步。 一、Maven简介 Maven是Apache旗下的一款项目管理工具,是...

星汉
今天
0
0
小程序Aes解密

主要步骤: 1、下载AES源码(JS版) 2、在小程序中新建一个公共的文件夹,把AES源码拷贝进去(注意:需要暴露接口 module.exports = CryptoJS;) 3、添加一个用于加密解密的公共JS,可取名为...

Mr_Tea伯奕
今天
0
0
Go实现文件传输(基本传输可用)

发送端 package mainimport ("fmt""os""net""io")func SendFile(path string, connect net.Conn){file, oerr :=os.Open(path)if oerr !=nil{fmt.Println("Open", oerr)......

CHONGCHEN
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部