JNA简介及使用_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > JNA简介及使用

JNA简介及使用

 2013/9/12 21:52:35  forestqqqq  程序员俱乐部  我要评论(0)
  • 摘要:JNA全称JavaNativeAccess,是一个建立在经典的JNI技术之上的Java开源框架(https://github.com/twall/jna)。JNA提供一组Java工具类用于在运行期动态访问系统本地库(nativelibrary:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标nativelibrary的函数与结构,JNA将自动实现Java接口到nativefunction的映射。JNA包:https://maven
  • 标签:使用 简介

class="MsoNormal">JNA全称Java Native Access,是一个建立在经典的JNI技术之上的Java开源框架(https://github.com/twall/jna)。JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Windowdll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

JNA包:

https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/4.0.0/jna-4.0.0.jar

https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna-platform/4.0.0/jna-platform-4.0.0.jar

?

JNA在线帮助文档:http://twall.github.io/jna/4.0/javadoc/

JNA入门示例:https://github.com/twall/jna/blob/master/www/GettingStarted.md

1dllsoC函数的集合和容器,这与Java中的接口概念吻合,所以JNAdll文件和so文件看成一个个接口。在JNA中定义一个接口就是相当于了定义一个DLL/SO文件的描述文件,该接口代表了动态链接库中发布的所有函数。而且,对于程序不需要的函数,可以不在接口中声明。

2JNA定义的接口一般继承com.sun.jna.Library接口,如果dll文件中的函数是以stdcall方式输出函数,那么,该接口就应该继承com.sun.jna.win32.StdCallLibrary接口。

3Jna难点:编程语言之间的数据类型不一致。

JavaC的数据类型对照表

Java?类型

C?类型

原生表现

?boolean

?int

?32位整数 (可定制)

?byte

?char?

?8位整数

?char

?wchar_t

?平台依赖

?short

?short

?16位整数

?int

?int

?32位整数

?long

long long, __int64

?64位整数

?float

?float

?32位浮点数

?double

?double

?64位浮点数

?Buffer/Pointer

?pointer

?平台依赖(32 64位指针)

?<T>[] (基本类型的数组)

?pointer/array

32 64位指针(参数/返回值)

邻接内存(结构体成员)

?String

?char*

/0结束的数组 (native encoding or jna.encoding)

?WString

?wchar_t*

?/0结束的数组(unicode)

?String[]

?char**

?/0结束的数组的数组

?WString[]

?wchar_t**

?/0结束的宽字符数组的数组

?Structure

?struct*/struct

指向结构体的指针 (参数或返回值) (或者明确指定是结构体指针)
结构体(结构体的成员) (或者明确指定是结构体)

?Union

union?

?等同于结构体

?Structure[]

?struct[]

?结构体的数组,邻接内存

?Callback

?<T> (*fp)()

?Java函数指针或原生函数指针

?NativeMapped

?varies

?依赖于定义

?NativeLong

?long

?平台依赖(3264位整数)

?PointerType

?pointer

? Pointer相同

?

4,简单使用示例:

?

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
 
interface HelloInter extends Library{
   int toupper(int ch);
   double pow(double x,double y);
   void printf(String format,Object... args);
}
public class HelloWorld {
  
   public static void main(String [] args){
      HelloInter INSTANCE =
           (HelloInter)Native.loadLibrary(
                 Platform.isWindows()?"msvcrt":"c",
                      HelloInter.class);
      INSTANCE.printf("Hello, World\n");
      String [] strs = new String[]{"芙蓉","如花","凤姐"};
        for (int i=0;i < strs.length;i++) {
            INSTANCE.printf("人物 %d: %s\n", i, strs[i]);
        }
        System.out.println("pow(2d,3d)=="+INSTANCE.pow(2d, 3d));
        System.out.println("toupper('a')=="+(char)INSTANCE.toupper((int)'a'));
   }
 
}

?

运行结果:

pow(2d,3d)==8.0
toupper('a')==A
Hello, World
人物 0: 芙蓉
人物 1: 如花
人物 2: 凤姐

?

?

5,示例说明:

HelloInter接口中定义的3个函数全是C语言函数库中的函数,其定义格式如下:

int toupper(int ch)
double pow( double x, double y )
int printf(const char* format, ...)

?

C语言函数库中有很多个函数,但是我们只用到了这3个函数,所以其他的函数不需要声明在接口中。

注意:Java接口中的参数类型和C语言参数类型之间的对应关系(见第3条,对照表)

6,结构体参数和结构体指针。

(1)Structure子类中的公共字段的顺序,必须和C语言中的结构体的顺序保持一致,否则会出错。

(2)Structure的使用参见:http://www.doc88.com/p-31975835542.html

注意:跨平台调用函数会影响系统性能应尽量使用基本、简单的数据类型,而且,尽量少跨语言、跨平台传递数据

?

参考文章:

深入浅出JNA—快速调用原生函数:http://www.doc88.com/p-31975835542.html

JNA—JNI终结者: http://blog.csdn.net/shendl/article/details/3589676

JNA的使用:http://xbgd.iteye.com/blog/1044864

深入理解JNA—模拟C语言结构体:http://blog.csdn.net/shendl/article/details/3599849

?

?

?

?

发表评论
用户名: 匿名