您好,欢迎访问三七文档
L/O/G/OJNA技术讲解•JAVA本地接口(JAVANativeInterface,JNI)。JNI是本地编程接口。它使得在JAVA虚拟机内部运行的JAVA代码能够与用其他编程语言(如C、C++和汇编语言)编写的应用程序和库进行互操作•从JAVA1.1开始,JAVANativeInterface标准成为JAVA平台的一部分,它允许JAVA代码和其他语言写的代码进行交互•JNI一开始是为了本地已编译诞,尤其是C和C++而设定的。但是它并不妨碍你使用其他语言,只要调用约定受支持的就可以•JAVA通过JNI调用本地方法,而本地方法是以库文件形式存放的。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统的各个接口方法JNI产生背景•应用程序需要使用系统相关的功能,而JAVA代码不支持或是难以办到•已有其他语言写好的类库或程序,希望JAVA程序可以使用它们JAVA本地接口的方法•出于更高的性能要求,希望使用汇编或者C/C++语言来实现部分功能JNI的使用步骤1.编写JAVA代码。编写一个JAVA类,需要执行三个任务:使用关键字Native声明将要调用的本机方法;loadLibrary加载包含本机代码的共享库;然后调用该本机方法2.编译JAVA代码。在使用JAVA类之前,必须成功的将它们编译成字节码,即使用javac命令编译成.class文件3.创建C/C++头文件。C/C++头文件将声明想要调用的本机函数说明。使用javah命令编译.h后缀名结尾的头文件4.编写C/C++代码。需要使用C语言编写第三步中源代码文件中的函数。必须导入jni.h文件和步骤三中创建的头文件JNI的使用步骤5.创建共享库文件。根据C语言编写的代码利用工具创建共享库文件。6.运行JAVA程序。把创建的库文件导入后执行代码看是否有效。JNI的弊端•使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的。•如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另外使用C语言写一个.dll/.so共享库,使用SUN规定的数据结构替代C语言的数据结构,调用已有的dll/so中公布的函数。•然后再在Java中载入这个适配器dll/so,再编写Javanative函数作为dll中函数的代理。•经过2个繁琐的步骤才能在Java中调用本地代码。JNA简介•JNA(JAVANativeAccess)框架是一个开源的JAVA框架,是SUN公司主导开发的,建立在经典的JNI的基础上的一个框架,它使您可以方便地使用java直接访问动态链接库中的函数。•JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射。你不再需要编写C动态链接库。•使用JNA技术比使用JNI技术调用动态链接库会有些微的性能损失。可能速度会降低几倍。但影响不大。JNA技术难点•当前路径是在项目下,而不是bin输出目录下。(此处将在后面的具体工程中解释)•数据结构的对应关系。(具体数据结构参考JNA文档)JNA引入动态链接库•通过JNA建立与动态链接库的映射很容易,只需创建一个接口,调用Native的loadLibrary方法即可)•publicinterfaceCLibraryextendsLibrary{•CLibraryINSTANCE=(CLibrary)Native.loadLibrary(•“msvcrt”,CLibrary.class);•}JNA建立与库函数的对应关系•JNA建立与动态链接库中函数的对应关系,只需在加载了相应类库的接口中声明这个函数即可•PublicinterfaceCLibraryextendsLibrary{•voidprintf(Stringformat,Object...args);•}JNA基本数据类型对应JavaTypeCTypeNativeRepresentationbooleanint32-bitinteger(customizable)bytechar8-bitintegercharwchar_tplatform-dependentshortshort16-bitintegerintint32-bitintegerlonglonglong,__int6464-bitintegerfloatfloat32-bitfloatingpointdoubledouble64-bitfloatingpointBufferPointerpointerplatform-dependent(32-or64-bitpointertomemory)T[](arrayofprimitivetype)pointerarray32-or64-bitpointertomemory(argument/return)contiguousmemory(structmember)JNA基本数据类型对应Stringchar*NUL-terminatedarray(nativeencodingorjna.encoding)WStringwchar_t*NUL-terminatedarray(unicode)String[]char**NULL-terminatedarrayofCstringsWString[]wchar_t**NULL-terminatedarrayofwideCstringsStructurestruct*structpointertostruct(argumentorreturn)(orexplicitly)structbyvalue(memberofstruct)(orexplicitly)UnionunionsameasStructureStructure[]struct[]arrayofstructs,contiguousinmemoryCallbackT(*fp)()functionpointer(Javaornative)NativeMappedvariesdependsondefinitionNativeLonglongplatform-dependent(32-or64-bitinteger)PointerTypepointersameasPointerJNA小示例•在Java项目中引入jna.jar包•创建一个Clibrary接口•publicinterfaceCLibraryextendsLibrary{•CLibraryINSTANCE=(CLibrary)Native.loadLibrary((Platform.isWindows()?msvcrt:c),•CLibrary.class);•voidprintf(Stringformat,Object...args);•}JNA小示例•写一个HelloTest类进行测试•publicclassHelloTest{•publicstaticvoidmain(String[]args){•CLibrary.INSTANCE.printf(Hello,World\n);•}•}JNA的不足JNA是建立在JNI技术基础之上的一个框架。使用JNI技术,不仅可以实现Java访问C函数,也可以实现C语言调用Java代码。而JNA只能实现Java访问C函数,作为一个Java框架,自然不能实现C语言调用Java代码。此时,你还是需要使用JNI技术。JNA动态链接库加载路径研究•JNA加载动态连接库有一下五种方式1.JAVA工程下2.在系统的system32文件夹下3.JAVA的jdk安装目录的lib文件夹下4.JAVA的jdk安装目录的jre的bin目录下5.JAVA的jdk安装目录的bin目录下JNI简介JNI产生的背景1什么是JNI2JAVA本地接口概述3JAVA本地接口方法4利用JNI编程5JNI回顾JNI简介1JNI设计概述2JNI函数3JNI类型和数据结构4调用API函数5JAVA本地接口概述•调用JAVA本地方法的时机
本文标题:JNA技术讲解
链接地址:https://www.777doc.com/doc-7842007 .html