http://blog.csdn.net/shendl/archive/2008/12/24/3589676.aspx
介绍
给大家介绍一个最新的访问本机代码的
Java
框架
—JNA
。
JNA(Java Native Access)
框架是一个开源的
Java
框架,是
SUN
公司主导开发的,建立在经典的
JNI
的基础之上的一个框架。
JNA
项目地址:
https://jna.dev.java.net/
非常强大、易用,功能上类似与
.NET
的
P/Invoke
。
不堪回首的
JNI
我们知道,使用
JNI
调用
.dll/.so
共享类库是非常非常麻烦和痛苦的。
如果有一个现有的
.dll/.so
文件,如果使用
JNI
技术调用,我们首先需要另外使用
C
语言写一个
.dll/.so
共享库,使用
SUN
规定的数据结构替代
C
语言的数据结构,调用已有的
dll/so
中公布的函数。
然后再在
Java
中载入这个适配器
dll/so
,再编写
Java
native
函数作为
dll
中函数的代理。
经过
2
个繁琐的步骤才能在
Java
中调用本地代码。
因此,很少有
Java
程序员愿意编写调用
dll/.so
库中的原生函数的
java
程序。这也使
Java
语言在客户端上乏善可陈。可以说
JNI
是
Java
的一大弱点!
.NET
平台上强大的
P/Invoke
而在
.NET
平台上,强大的
P/Invoke
技术使我们
Java
程序员非常羡慕。使用
P/Invoke
技术,只需要使用编写一个
.NET
函数,再加上一个声明的标注,就可以直接调用
dll
中的函数。
不需要你再使用
C
语言编写
dll
来适配。
不逊于
P/Invoke
的
JNA
现在,不需要再羡慕
.NET
的
P/Invoke
机制了。
JNA
把对
dll/.so
共享库的调用减少到了和
P/Invoke
相同的程度。
使用
JNA
,不需要再编写适配用的
.dll/.so
,只需要在
Java
中编写一个接口和一些代码,作为
.dll/.so
的代理,就可以在
Java
程序中调用
dll/so
。
JNA
快速启动
现在让我们直接进入
JNA
的世界。
你只需要下载一个
jar
包,就可以使用
JNA
的强大功能方便地调用动态链接库中的
C
函数。
1
,下载
jna.jar
。
在这里
https://jna.dev.java.net/servlets/ProjectDocumentList?folderID=7408&expandFolder=7408&folderID=0
2
,现在你已经可以使用
JNA
了。
为了方便你参考
JNA
的
java
类库,我制作了《
JNA3.09API
参考手册》,是
CHM
格式的。你可以到这里下载
http://download.csdn.net/source/900438
JNA
例子
例子
1
现在让我们运行一个
JNA
程序,感受它的强大威力。
1
,在
Java
项目中引入
jna.jar
包。
2
,创建一个类:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
/** Simple example of native library declaration and usage. */
public class HelloWorld {
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]);
}
}
}
3
,执行,可以看到控制台中打印出了
Hello, World
但是,请注意,这个程序实际上是使用
msvcrt.dll
这个
C
运行时库中的
printf
函数打印出上面这些字符的。
看,多简单,不需要写一行
C
代码,就可以直接在
Java
中调用外部动态链接库中的函数!
例子
2
上面那个例子使用了操作系统自带的动态链接库,现在我们再自己写一个动态链接库试试。
1
,在
VS
中选择
C++
语言,然后选择创建一个
Win32
程序。
选择
dll
类型。
2
,发布的
C
函数是:
#define
MYLIBAPI
extern
"C"
__declspec
(
dllexport
)
MYLIBAPI
void
say(
wchar_t
* pValue);
这个函数的实现是:
void
say(
wchar_t
* pValue){
std::wcout.imbue(std::locale(
"chs"
));
std::wcout<<L
"上帝说:"
<<pValue<<std::endl;
}
它需要传入一个
Unicode
编码的字符数组。然后在控制台上打印出一段中文字符。
3
,生成
dll
。然后把生成的
dll
文件复制到
Eclipse
项目中,放在项目下面。
4
,在
Eclipse
中编写以下代码:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.WString;
/**
* @author
沈东良
Edward Shen shendl_s@hotmail.com
* 2008-11-23
下午
05:07:14
*TestDll1.dll
*/
public class TestDll1Service {
public interface TestDll1 extends Library {
/**
*
当前路径是在项目下,而不是
bin
输出目录下。
*/
TestDll1 INSTANCE = (TestDll1)Native.loadLibrary("TestDll1", TestDll1.class);
public void say(WString value);
}
/**
*
*/
public TestDll1Service() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestDll1.INSTANCE.say(new WString("Hello World!"));
System.out.println("HHEEH
我我们无法万恶
");
}
}
5
,执行这个
Java
类。可以看到控制台下如下输出:
上帝说:
Hello World!
HHEEH
我我们无法万恶
6
,上面一行是
C
语言使用
C++
的
std::wcout
输出的。
下面一行是
Java
语言输出的。
JNA
技术解密
JNA
工作原理
JNA
是建立在
JNI
技术基础之上的一个
Java
类库,它使您可以方便地使用
java
直接访问动态链接库中的函数。
原来使用
JNI
,你必须手工用
C
写一个动态链接库,在
C
语言中映射
Java
的数据类型。
JNA
中,它提供了一个动态的
C
语言编写的转发器,可以自动实现
Java
和
C
的数据类型映射。你不再需要编写
C
动态链接库。
当然,这也意味着,使用
JNA
技术比使用
JNI
技术调用动态链接库会有些微的性能损失。可能速度会降低几倍。但影响不大。
JNA
技术难点
1
,当前路径是在项目下,而不是
bin
输出目录下。
2
,数据结构的对应关系:
Java—C
和操作系统数据类型的对应表
Java Type
|
C Type
|
Native Representation
|
boolean
|
int
|
32-bit integer (customizable)
|
byte
|
char
|
8-bit integer
|
char
|
wchar_t
|
platform-dependent
|
short
|
short
|
16-bit integer
|
int
|
int
|
32-bit integer
|
long
|
long long, __int64
|
64-bit integer
|
float
|
float
|
32-bit floating point
|
double
|
double
|
64-bit floating point
|
Buffer
Pointer
|
pointer
|
platform-dependent (32- or 64-bit pointer to memory)
|
<T>[] (array of primitive type)
|
pointer
array
|
32- or 64-bit pointer to memory (argument/return)
contiguous memory (struct member)
|
除了上面的类型,
JNA
还支持常见的数据类型的映射。
|
String
|
char*
|
NUL-terminated array (native encoding or
jna.encoding
)
|
WString
|
wchar_t*
|
NUL-terminated array (unicode)
|
String[]
|
char**
|
NULL-terminated array of C strings
|
WString[]
|
wchar_t**
|
NULL-terminated array of wide C strings
|
Structure
|
struct*
struct
|
pointer to struct (argument or return) (
or explicitly
)
struct by value (member of struct) (
or explicitly
)
|
Union
|
union
|
same as
Structure
|
Structure[]
|
struct[]
|
array of structs, contiguous in memory
|
Callback
|
<T> (*fp)()
|
function pointer (Java or native)
|
NativeMapped
|
varies
|
depends on definition
|
NativeLong
|
long
|
platform-dependent (32- or 64-bit integer)
|
PointerType
|
pointer
|
same as
Pointer
|
styl
分享到:
相关推荐
**标题:“JNA—JNI终结者”** 这篇文章探讨的主题是Java Native Access (JNA) 和 Java Native Interface (JNI),两者都是Java平台上的技术,用于在Java应用程序中调用本地(非Java)代码。它们允许Java程序员与...
### 使用JNA替代JNI调用DLL,并解决内存溢出问题 #### 问题背景 在项目的开发过程中,常常遇到需要处理二进制流数据并对其进行解析处理的情况。这种情况下,如果上层应用平台采用的是Java开发,而底层算法或数据...
《JNI与JNA在Spring Boot 2.3.0中的应用探索》 JNI(Java Native Interface)和JNA(Java Native Access)是Java平台中用于与本地代码交互的两种主要技术。它们允许Java应用程序调用C、C++等本地库,从而扩展Java的...
在这种情况下,"springboot+jna/jni调用动态so/dll库"是一个重要的主题,它涉及到Spring Boot应用如何利用Java Native Interface (JNI) 和 Java Native Access (JNA) 这两种技术来调用操作系统级别的动态链接库(.so...
这里我们主要探讨两种方式:JNI(Java Native Interface)和JNA(Java Native Access)。这两种技术允许Java代码与本地代码进行交互,使得Java开发者能够利用非Java编写的库或操作系统功能。 首先,JNI是Java平台...
JNI(Java Native Interface)和JNA(Java Native Access)都是Java平台上的原生接口技术,允许Java代码与操作系统底层交互,调用本地库。它们在功能上类似,但实现方式不同,因此性能也有所差异。 ### JNI JNI是...
JNI 和 JNA 的比较 尽管示例适用于所有平台,但 Makefile 仅适用于 Linux 和 OSX。 因此,这些是唯一受支持的平台 该存储库包含两个子项目,一个用于 JNI,一个用于 JNA。 实现的用例是 在 C 中生成一个随机数并从 ...
JNA—JNI终结者,java调用dll、ocx、so最简单的方法中提到的包 jna.jar
JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与...
JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native ...是JNI终结者。
JNA3.09API参考手册.chm 是我制作的JNA类库3.09版的Java API参考手册。方便查找。 JNA是最新的Java平台上调用动态链接库.dll/.so的类库。是JNI终结者。
分别用JNI和JNA的方式建立dll,dll中包含一个get方法和一个set方法,在java端进行循环调用1000*1000次,比较所耗费的时间。 结论:JNI消耗的总时间(16ms) JNA消耗的总时间(2593ms) 性能:JNI >> JNA
在Java世界中,有时我们需要利用Java Native Interface (JNI) 和 Java Native Access (JNA) 这两种技术来调用C++编写的动态链接库(DLL或SO文件),以实现Java程序与底层系统的交互。这两者都是Java平台上的关键组件,...
研究java调用dll的时候,大部分都是通过jni,比较麻烦,我找到了通过jna方法调用dll的方法,用起来比较方便,只需要引用jna.jar包,这个jar包已经包含在程序中,还包含了我调用dll的遇到难道的解决办法。
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的本地函数,而无需编写JNI(Java Native Interface)代码。JNI是Java与本机代码交互的标准方式,但它通常需要编写大量的C/...
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需编写任何C/C++代码或使用JNI(Java Native Interface)。JNA通过提供一种映射机制,将Java方法与本地库...
Java Native Interface (JNI) 和 Java Native Access (JNA) 是两种主要的机制,允许Java代码调用C/C++函数。本篇文章将详细讲解如何在Android中使用JNA来调用C/C++方法。 首先,了解JNA的基本概念。JNA是一种轻量级...
JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java...
JNA的出现是为了简化与本地代码交互的过程,它的目标是成为JNI的替代方案,因为JNI的使用通常涉及到大量的模板代码和编译步骤。 **JNA的核心概念:** 1. **Platform:** JNA的核心是一个`Platform`类,它包含了...
JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。在Android开发中,JNI常用于提升性能、调用系统库或者实现特定功能,如与C/C++库交互。本项目重点在于如何在JNI...