`
yangzb
  • 浏览: 3501000 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNA(Java Native Access)学习入门

 
阅读更多

Java Native Access 项目 在Java.net上,你可以到这个网站上现在这个项目的代码和在线帮助文档。虽然在下载有5个相关的jar文件,在本文中你仅仅需要下载其中的jna.jar和example.jar。

Jna.jar 提供基本的、运行这些示例文件必需的jna运行环境。这个jna.jar文件除了有Unix、Linux、Windows和Mac OS X平台相关的JNT-friendly本地库外,还包含其他几个类包。每一个本地库都是用来访问相对应平台下的本地方法的。

         example.jar包含了不同的示例来表明JNA的用途。其中的一个例子是使用JNA来实现一个在不同平台下的透明视窗技术的API。在文章最后的示 例中将要展示如何使用这个API修复上个月的文章关于VerifyAge2应用中辨认透明效果的问题。

获取本地时间(Get local time)

如果你在Java Native Access 首页 看过“JNA如何入门”,你就会知道一个很简单的关于调用Windows 平台下的API函数:GetSystemTime()的JNA示例。这个不完整的例子只是展示了JNA的基本特点。(在例子的基础上,我做了一个更完整的 基于Windows的例子来介绍JNA)我在 Windows平台下完善了这个例子来介绍JNA。

第一例子基于Windows GetLocalTime() API函数返回本地当前的时间和日期。和GetSystemTime()不同的是,返回的时间/日期是协调通用时间 (UTC)格式的,GetLocalTime()返回的时间/日期信息的格式是根据当前时区来表示。

在一个Java程序中使用JNA调用GetLocalTime,你需要知道这个函数所在的Windows平台下的动态链接库(DLL)的名称(和可能所在 的地理区域)。我们发现GetLocalTime()和GetSystemTime在同一个DLL文件中:kernel32.dll。你还需要知道 GetLocalTime()在C语言环境中的申明。申明如下Listing 1:

Listing 1. GetLocalTime在C语言中的申明

typedef struct
{
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
}
SYSTEMTIME, *LPSYSTEMTIME;

VOID GetLocalTime(LPSYSTEMTIME lpst);
这个基于C语言的申明表明传到这个函数的参数数目和类型。在这个例子中,只有一个参数---一个指向Windows SYSTEMTIME结构体的指针。而且,每个结构体成员的类型是16bit长度的无符号整型。根据这些信息,你能够创建一个完全描述 GetLocalTime()函数的接口,如Listing 2中所示:

Listing 2. Kernel32.java




// Kernel32.java

import com.sun.jna.*;
import com.sun.jna.win32.*;

public interface Kernel32 extends StdCallLibrary
{
    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 GetLocalTime (SYSTEMTIME result);
}


Kernel32 接口(The Kernel32 interface)

因为JNA使用通过一个接口来访问某个库中的函数,Listing 2表示了一个描述GetLocalTime()的接口。根据约定,我把接口命名为Kernel32是因为GetLocalTime()在Windows的kernel32.dll库。

这个接口必须继承com.sun..jna.Library接口。因为Windows API函数遵循stdcall调用协议(stdcall calling convention),为Windows API申明的接口也必须继承com.sun.jna.win32. StdCallLibrary接口。因此这个接口共继承了Library 和 com.sun.jna.win32.StdCall两个接口。

在前面,你已经知道了GetLocalTime() 需要一个指向SYSTEMTIME结构体的指针作为它唯一的参数。因为Java不支持指针,JNA是通过申明一个 com.sun.jna.Structure的子类来代替的。根据java文档中抽象类的概念,在参数环境中,Structure相当于C语言的 struct*。

在SYSTEMTIME类中的字段和C结构体中的相对应的属性字段的顺序是一一对应的。保证字段顺序的一致性是非常重要的。例如,我发现交换wYear和wMonth会导致wYear和wMonth值互换。

每个字段在java中是short integer类型的。按照JNA首页上 “默认类型映射”章节给出的提示,这个short integer分配类型是正确。然而,我们应该知道一个重要的区别:Windows平台下的WORD类型等同于C语言环境中的16-bit的无符号的 short integer,而java中short integer是16-bit有符号的short integer。

一个类型映射的问题

通过比较一个API 函数返回的整型值,你会发现Windows/C 语言的无符号整型和Java语言的有符号整型的JNA类型映射是有问题的。在比较的过程中,如果你不细心,那么错误的执行过程可能导致决定性情况。导致这种后果是因为忘记任何数值的符号位的确定是根据:在无符号整型的情况下会被解释为正号,而在有符号整型的进制中被理解为负号的。

通过Kernel32获取本地时间(Access the local time with Kernel32)

JNA 首页上的GetSystemTime()示例已经表明必须使用预先申明的接口为本地库分配一个实例对象。你可以通过com.sun.jna.Native 类中静态公用方法loadLibrary(String name, Class interfaceClass)来完成上述的目标。Listing 3 所示:

Listing 3. LocalTime.java

// LocalTime.java

import com.sun.jna.*;

public class LocalTime
{
    public static void main (String [] args)
    {
       Kernel32 lib = (Kernel32) Native.loadLibrary ("kernel32",
                                                     Kernel32.class);
       Kernel32.SYSTEMTIME time = new Kernel32.SYSTEMTIME ();
       lib.GetLocalTime (time);
       System.out.println ("Year is "+time.wYear);
       System.out.println ("Month is "+time.wMonth);
       System.out.println ("Day of Week is "+time.wDayOfWeek);
       System.out.println ("Day is "+time.wDay);
       System.out.println ("Hour is "+time.wHour);
       System.out.println ("Minute is "+time.wMinute);
       System.out.println ("Second is "+time.wSecond);
       System.out.println ("Milliseconds are "+time.wMilliseconds);
    }
}


Listing 3 执行Kernel32 lib = (Kernel32) Native.loadLibrary ("kernel32", Kernel32.class);来分配一个Kernel32实例对象并且装载kernel32.dll。因为kernel32.dll是Windows 平台下标准的dll文件,所以不要指定访问这个库的路径。然而,如果找不到这个dll文件,loadLibrary()会抛出一个 UnsatisfiedLinkError异常。

Kernel32.SYSTEMTIME time = new Kernel32.SYSTEMTIME ();创建了一个SYSTEMTIME结构体的示例。初始化后下面是lib.GetLocalTime (time);,这句话使用本地的时间/日期来给这个实例赋值。几个System.out.println()语句是输出这些值。

编译和运行这个应用(Compile and run the application)

这部分很容易。假设jna.jar、Kernel32.java和LocalTime.java是放在当前文件夹中,调用java –cp jna.jar;. LocalTime.java来编译这个应用的源代码。如果在Windows平台下,调用invoke java –cp jna.jar;. LocalTime 来运行这个应用。你可以得到类似与Listing 4的输出结果:

Listing 4. 从LocalTime.java生成的输出

Year is 2007
Month is 12
Day of Week is 3
Day is 19
Hour is 12
Minute is 35
Second is 13
Milliseconds are 156


获取操纵杆信息(Accessing joystick device info)

上面的例子已经介绍了JNA,但是这个获取本地时间和日期的例子并没有很好的利用这个技术,甚至也没有体现JNI的价值。Java语言中的 System.currentTimeMillis()函数已经以毫秒的格式返回了这些信息。因为Java语言没有为游戏控制器提供API,所以获取操纵杆的信息更适合JNA的使用。

例如,你要构建一个平台无关的Java库,而且这些库使用JNA调用Linux, Mac OS X, Windwos和Unix平台中本地的操纵杆API。为了简洁和方便起见,这个例子仅仅是调用Windows平台下的操纵杆API。而且我将重点介绍这个 API很小的一部分。

类似GetLocalTime(),第一步是辨别出操作杆API的DLL,这个DLL是winmm.dll,和 kernel32.dll在同一个文件夹中,它包含了操作杆的API和其他的多媒体APIs。还需知道要被使用的操作杆函数基于C语言的声明。这些函数声明已经在Listing 5中列出来了。

Listing 5. C-based declarations for some Joystick API functions

#define MAXPNAMELEN 32

typedef struct
{
    WORD   wMid;                   // manufacturer identifier
    WORD   wPid;                   // product identifier
    TCHAR szPname  MAXPNAMELEN

 ; // product name
    UINT   wXmin;                  // minimum x position
    UINT   wXmax;                  // maximum x position
    UINT   wYmin;                  // minimum y position
    UINT   wYmax;                  // maximum y position
    UINT   wZmin;                  // minimum z position
    UINT   wZmax;                  // maximum z position
    UINT   wNumButtons;            // number of buttons
    UINT   wPeriodMin;             // smallest supported polling interval when captured
    UINT   wPeriodMax;             // largest supported polling interval when captured
}
JOYCAPS, *LPJOYCAPS;

MMRESULT joyGetDevCaps(UINT IDDevice, LPJOYCAPS lpjc, UINT cbjc);

UINT joyGetNumDevs(VOID);


操作杆API的函数(Functions of the Joystick API)

在Windows平台下是通过以joy作为函数名开始的函数以及被各种函数调用的结构体来实现操作杆API的。例如,joyGetNumDevs()返回的是这个平台下支持的操作杆设备最多的数目;joyGetDevCaps()返回的是每个连接上的操纵杆的质量。

joyGetDevCaps()函数需要3个参数:
* 处在0到joyGetNumDevs()-1之间的操作杆ID
* 保存返回的质量信息的JOYCAPS结构体的地址
* JOYCAPS结构体的字节大小
虽然它的结果不同,这个函数返回的是一个32位的无符号整型结果,而且0表示一个已经连接的操纵杆。

JOYCAPS 结构体有3种类型。Windows平台下的WORD(16位无符号短整型)类型对应的是Java语言中16位有符号短整型。除此之外,Windows下的 UINT(32位无符号整型)类型是和Java语言中32位有符号整型相对应的。而Windows平台上的text character就是TCHAR类型。

微软通过TCHAR类型使开发人员能够从ASCII类型的函数参数平滑的转移到Unicode字符类型的函数参数上。而且,拥有text类型参数的函数的实现是通过宏转变为对应的ASCII或者wide-character的函数。例如,joyGetDevCaps()是一个对应joyGetDevCapsA() 和 joyGetDevCapsW()的宏。

使用TCHAR(Working with TCHAR)

使用TCHAR和将TCHAR转变的宏会导致基于C语言的申明向基于JNA接口的转换
变得有点复杂—你在使用ASCII或者wide-character版本的操纵杆函数吗?两种版本都在如下的接口中展示了:

Listing 6. WinMM.java

// WinMM.java

import com.sun.jna.*;
import com.sun.jna.win32.*;

public interface WinMM extends StdCallLibrary
{
    final static int JOYCAPSA_SIZE = 72;

    public static class JOYCAPSA extends Structure
    {
       public short wMid;
       public short wPid;
       public byte szPname [] = new byte [32];
       public int wXmin;
       public int wXmax;
       public int wYmin;
       public int wYmax;
       public int wZmin;
       public int wZmax;
       public int wNumButtons;
       public int wPeriodMin;
       public int wPeriodMax;
    }

    int joyGetDevCapsA (int id, JOYCAPSA caps, int size);

    final static int JOYCAPSW_SIZE = 104;

    public static class JOYCAPSW extends Structure
    {
       public short wMid;
       public short wPid;
       public char szPname [] = new char [32];
       public int wXmin;
       public int wXmax;
       public int wYmin;
       public int wYmax;
       public int wZmin;
       public int wZmax;
       public int wNumButtons;
       public int wPeriodMin;
       public int wPeriodMax;
    }

    int joyGetDevCapsW (int id, JOYCAPSW caps, int size);

    int joyGetNumDevs ();
}


Listing 6没有介绍JNA的新特性。实际上,JNA强调了对本地库的接口命名规则。同时,还展示了如何将TCHAR映射到Java语言中的byte和char数组。最后,它揭示了以常量方式声明的结构体的大小。Listing 7展示了当调用joyGetDevCapsA() 和 joyGetDevCapsW()时如何使用这些常量。

Listing 7. JoystickInfo.java

// JoystickInfo.java

import com.sun.jna.*;

public class JoystickInfo
{
    public static void main (String [] args)
    {
       WinMM lib = (WinMM) Native.loadLibrary ("winmm", WinMM.class);
       int numDev = lib.joyGetNumDevs ();

       System.out.println ("joyGetDevCapsA() Demo");
       System.out.println ("---------------------\n");

       WinMM.JOYCAPSA caps1 = new WinMM.JOYCAPSA ();
       for (int i = 0; i < numDev; i++)
            if (lib.joyGetDevCapsA (i, caps1, WinMM.JOYCAPSA_SIZE) == 0)
            {
                String pname = new String (caps1.szPname);
                pname = pname.substring (0, pname.indexOf ('\0'));
                System.out.println ("Device #"+i);
                System.out.println ("   wMid = "+caps1.wMid);
                System.out.println ("   wPid = "+caps1.wPid);
                System.out.println ("   szPname = "+pname);
                System.out.println ("   wXmin = "+caps1.wXmin);
                System.out.println ("   wXmax = "+caps1.wXmax);
                System.out.println ("   wYmin = "+caps1.wYmin);
                System.out.println ("   wYmax = "+caps1.wYmax);
                System.out.println ("   wZmin = "+caps1.wZmin);
                System.out.println ("   wZmax = "+caps1.wZmax);
                System.out.println ("   wNumButtons = "+caps1.wNumButtons);
                System.out.println ("   wPeriodMin = "+caps1.wPeriodMin);
                System.out.println ("   wPeriodMax = "+caps1.wPeriodMax);
                System.out.println ();
            }

       System.out.println ("joyGetDevCapsW() Demo");
       System.out.println ("---------------------\n");

       WinMM.JOYCAPSW caps2 = new WinMM.JOYCAPSW ();
       for (int i = 0; i < numDev; i++)
            if (lib.joyGetDevCapsW (i, caps2, WinMM.JOYCAPSW_SIZE) == 0)
            {
                String pname = new String (caps2.szPname);
                pname = pname.substring (0, pname.indexOf ('\0'));
                System.out.println ("Device #"+i);
                System.out.println ("   wMid = "+caps2.wMid);
                System.out.println ("   wPid = "+caps2.wPid);
                System.out.println ("   szPname = "+pname);
                System.out.println ("   wXmin = "+caps2.wXmin);
                System.out.println ("   wXmax = "+caps2.wXmax);
                System.out.println ("   wYmin = "+caps2.wYmin);
                System.out.println ("   wYmax = "+caps2.wYmax);
                System.out.println ("   wZmin = "+caps2.wZmin);
                System.out.println ("   wZmax = "+caps2.wZmax);
                System.out.println ("   wNumButtons = "+caps2.wNumButtons);
                System.out.println ("   wPeriodMin = "+caps2.wPeriodMin);
                System.out.println ("   wPeriodMax = "+caps2.wPeriodMax);
                System.out.println ();
            }
    }
}

尽管和LocalTime这个示例类似,JoystickInfo执行WinMM lib = (WinMM) Native.loadLibrary ("winmm", WinMM.class);这句话来获取一个WinMM的实例,并且载入winmm.dll。它还执行WinMM.JOYCAPSA caps1 = new WinMM.JOYCAPSA (); 和 WinMM.JOYCAPSW caps2 = new WinMM.JOYCAPSW ();初始化必需的结构体实例。

编译和运行这个程序(Compile and run the application)

假如jna.jar,WinMM.java和JoystickInfo.java在同一个文件夹中,调用 javac -cp jna.jar;. JoystickInfo.java 来编译这个应用的源代码。
在windows平台下,调用java -cp jna.jar;. JoystickInfo就可以运行这个应用程序了。如果没有操纵杆设备,你应该得到Listing 8中的输出。

将C语言中的string类型转换为Java语言的String类型

pname = pname.substring (0, pname.indexOf ('\0')); 这段代码将一个C string 转换成了Java string. 如果不使用这个转换,C语言的string结束符’\0’和string后面的无用字符都会成为Java语言中String实例对象的内容。

Listing 8. 输出操纵杆信息(Output of JoystickInfo)

joyGetDevCapsA() Demo
---------------------

joyGetDevCapsW() Demo
---------------------


上面的输出是因为每次调用joyGetDevCap()返回的是一个非空值,这表示没有操纵杆/游戏控制器设备或者是出现错误。为了获取更多有意思的输出,将一个设备连接到你的平台上并且再次运行JoystickInfo。如下,将一个微软SideWinder即插即用游戏触摸板设备联上之后我获取了如下的输出:

Listing 9. 操纵杆连接上之后的运行结果(Output after running JoystickInfo with a joystick attached)

joyGetDevCapsA() Demo
---------------------

Device #0
   wMid = 1118
   wPid = 39
   szPname = Microsoft PC-joystick driver
   wXmin = 0
   wXmax = 65535
   wYmin = 0
   wYmax = 65535
   wZmin = 0
   wZmax = 65535
   wNumButtons = 6
   wPeriodMin = 10
   wPeriodMax = 1000

joyGetDevCapsW() Demo
---------------------

Device #0
   wMid = 1118
   wPid = 39
   szPname = Microsoft PC-joystick driver
   wXmin = 0
   wXmax = 65535
   wYmin = 0
   wYmax = 65535
   wZmin = 0
   wZmax = 65535
   wNumButtons = 6
   wPeriodMin = 10
   wPeriodMax = 1000


窗口透明度(Transparent windows)

在这系列文章中上篇文章是关于Bernhard Pauler's 气泡提示(balloontip)工程的。我构建了一个叫做VerifyAge的、包含有一个气泡提示的GUI应用。Figure 1中显示了这个GUI应用的一个小问题:这个气泡提示的没有经过修饰的对话框部分遮住了应用窗口的一部分边框,导致了无法点击这个边框的最小化和最大化按钮,并且使整个GUI很难看.
image
尽管未修饰部分的对话框不能显示气泡提示的透明度,java语言不支持窗口透明度。幸运的是,我们可以通过使用com.sun.jna.examples.WindowUtils类调用JNA的examples.jar文件来解决这个问题。
WindowUtils 提供在Unix,Linux,Mac OS X和Windows平台上使用JNA’s来实现窗口透明的工具方法。例如, public static void setWindowMask(final Window w, Icon mask) 让你根据像素而不是通过预定的掩罩(mask)参数来选取某部分的窗口。这个功能将在Listing 10中展示:

Listing 10. Using JNA to render a window transparent

// Create a mask for this dialog. This mask has the same shape as the
// dialog's rounded balloon tip and ensures that only the balloon tip
// part of the dialog will be visible. All other dialog pixels will
// disappear because they correspond to transparent mask pixels.

// Note: The drawing code is based on the drawing code in
// RoundedBalloonBorder.

Rectangle bounds = getBounds ();
BufferedImage bi = new BufferedImage (bounds.width, bounds.height,
                                       BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics ();
g.fillRoundRect (0, 0, bounds.width, bounds.height-VERT_OFFSET,
                  ARC_WIDTH*2, ARC_HEIGHT*2);
g.drawRoundRect (0, 0, bounds.width-1, bounds.height-VERT_OFFSET-1,
                  ARC_WIDTH*2, ARC_HEIGHT*2);
int [] xPoints = { HORZ_OFFSET, HORZ_OFFSET+VERT_OFFSET, HORZ_OFFSET };
int [] yPoints = { bounds.height-VERT_OFFSET-1, bounds.height-VERT_OFFSET
                    -1, bounds.height-1 };
g.fillPolygon (xPoints, yPoints, 3);
g.drawLine (xPoints [0], yPoints [0], xPoints [2], yPoints [2]);
g.drawLine (xPoints [1], yPoints [1], xPoints [2], yPoints [2]);
g.dispose ();
WindowUtils.setWindowMask (this, new ImageIcon (bi));


在Listing 10中的代码段是从本文代码文档(code archive )里的加强版的VerifyAge2 应用中的TipFrame的构造函数结尾部分摘录的。这个构造函数定义了围绕提示气泡的掩罩(mask)的形状,在这个形状范围里描绘不透明的像素。
假如你当前文件夹中有examples.jar, jna.jar, 和 VerifyAge2.java,调用 javac -cp examples.jar;balloontip.jar VerifyAge2.java 来编译源文件.然后调用java -Dsun.java2d.noddraw=true -cp examples.jar;balloontip.jar;. VerifyAge2运行这个应用. Figure 2 展示了透明示例.
image

总结(In conclusion)

JNA项目有很长的历史了(追溯到1999年),但是它第一次发布是在2006年11月。从此以后它慢慢的被需要将本地C代码整合到Java工程中的开发者注意到了。因为JNA能够用来解决JuRuby中常见一个问题:缺乏对POSIX调用的支持(lack of support for POSIX calls ),它也在JRuby程序员中掀起些波浪。JNA也同样被作为实现用低级C代码继承Ruby的一种解决方案(extending Ruby with low-level C code )。
我喜欢使用JNA来工作,相信你也会发现它比使用JNI来访问本地代码更简单、更安全。无需多言,JNA还有更多的特性在本文中没有体现出来。查阅它的资源部分:获取这个开源java项目更多的信息(learn more about this open source Java project )。用它做demo,而且在论坛(discussion forum )上共享你的经验。 下一个月我会带着另一个开源项目回来的,这个开源项目会给你每天的java开发带来益处。

附录:WindowUtils.setWindowMask()的替代品

在刚刚写完这篇文章后,我发现java语言支持在6u10版本中支持窗口的透明和形状定制。读完Kirill Grouchnikov的博客后,我用WindowUtils.setWindowMask()的替代品修改了VerifyAge2,如下:
// Create and install a balloon tip shape to ensure that only this part
// of the dialog will be visible.

Rectangle bounds = getBounds ();
GeneralPath gp;
gp = new GeneralPath (new RoundRectangle2D.Double (bounds.x, bounds.y,
                                                    bounds.width,
                                                    bounds.height-
                                                    VERT_OFFSET,
                                                    ARC_WIDTH*2-1,
                                                    ARC_HEIGHT*2-1));
gp.moveTo (HORZ_OFFSET, bounds.height-VERT_OFFSET);
gp.lineTo (HORZ_OFFSET, bounds.height);
gp.lineTo (HORZ_OFFSET+VERT_OFFSET+1, bounds.height-VERT_OFFSET);
AWTUtilities.setWindowShape (this, gp);


这段代码使用新类AWTUtilities(在com.sun.awt包中),而且public void setWindowShape(Window w, Shape s)函数将TipFrame和JDialog窗口设置气泡形状。

作者资料

Jeff Friesen 是一名自由的软件开发人员,同时也是Java技术领域的的教育者。在他的javajeff.mb.ca网站上可以获取他发布的所有的Java文章和其他资料。

原文链接

Open source Java projects: Java Native Access

分享到:
评论
1 楼 zjcjava1 2014-03-25  
 

相关推荐

    jna包及示例和VS2010入门

    JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与...

    Java JNA使用参考手册.pdf

    JNA(Java Native Access)是一个基于经典JNI技术的Java开源框架,它允许Java应用程序动态地访问本机库,例如Windows系统的.dll文件,而无需编写任何JNI或本机代码。通过在Java接口中描述目标本机库的功能和结构,...

    JNA示例的C++代码

    **JNA(Java Native Access)** 是Java平台上的一个库,允许Java应用程序直接调用操作系统级别的函数,无需编写JNI(Java Native Interface)代码。JNA提供了更简单的接口来与本地库交互,使得开发者可以轻松地访问...

    开源项目JNA-中文翻译版

    **Java Native Access (JNA)** 是一个用于Java应用程序的开源库,它允许开发者无需编写任何C代码就能直接调用本地库。这对于那些希望在Java程序中使用本地平台功能的开发人员来说是一个巨大的福音,因为它避免了许多...

    java调用本地化(dll)实用文档

    **JNA**(Java Native Access)是一种允许Java程序直接访问本地操作系统API和其他本机库的技术。它提供了一种无需编译额外本地代码即可访问本地库的方法,这与传统的JNI(Java Native Interface)相比大大简化了过程...

    嵌入式开发学习笔记( java - c/c++ :从入门到入门 )

    3. JNA(Java Native Access):JNA是一个Java库,它提供了一种简易的方法,使得Java程序能够调用动态链接库(DLL或SO)中的函数,而无需编写JNI的本地方法接口。 4. DLL(Dynamic Link Library)和SO(Shared ...

    开源项目JavaNativeAccess借鉴.pdf

    Java Native Access(JNA)是一个开源项目,旨在简化Java程序对本地平台库的调用,无需使用Java Native Interface(JNI)及其繁琐的流程。JNI在某些情况下是必要的,比如当Java标准API没有提供所需功能,而本地库...

    一、JAVA调用海康威视SDK实现摄像头预览

    在JAVA中调用SDK,我们首先需要引入必要的库文件,这通常涉及到JNA(Java Native Access)或者JNI(Java Native Interface)技术。JNA允许JAVA程序直接调用C/C++级别的函数,而JNI则需要编写C/C++的本地方法库,然后...

    海康人脸设备上传文档以及说明文档/examples.jar/jna.jar

    2. **jna.jar**:Java Native Access(JNA)库,允许Java程序调用本机操作系统API,这里可能是用于在Java环境中与海康设备的底层驱动交互,提供跨平台的接口。 综上所述,该压缩包为开发者或系统集成商提供了全面的...

    嵌入式开发学习笔记

    文档中也提到了JNA(Java Native Access)作为JNI的一种替代技术,但在本笔记中作者选择了JNI,并对为什么没有使用JNA给出了自己的解释。 本笔记还提到了Makefile的使用,这是一种在Linux环境下自动化构建项目的...

    常用Jacob包

    Jacob(Java Object-Oriented Binding)...不过,随着技术的发展,一些新的库和框架如Apache POI、JACOB的替代品如JNA(Java Native Access)也逐渐出现,它们提供了更现代的解决方案,可能在某些场景下是更好的选择。

    Android-基于speex的语音录制

    - **JNA(Java Native Access)**:是另一种与本地库交互的方式,无需编写JNI头文件和本地方法,而是通过Java接口映射到本地库函数。 5. **配置MediaRecorder**:在使用Speex时,你需要自定义MediaRecorder的音频...

    sniff_help_sniff_

    5. **javaguide.chm**:Java 导航指南,对于 Java 开发者,这个文档将阐述如何利用 Java 语言与 Sniff 交互,可能涉及 JNA(Java Native Access)或者 JNI(Java Native Interface)。 6. **adaguide.chm**:ADA ...

    WebSphere MQ

    - **MQI(Message Queue Interface)与JNA(Java Native Access)**:对于更底层的控制,开发者可以通过JNA调用WMQ的C API,提供更丰富的功能。 **4. WebSphere MQ的编程** - **创建队列管理器**:每个WMQ环境的...

    cairo-starter

    然后,开发者可以使用Java Native Interface (JNI) 或者 Java Native Access (JNA) 来创建桥梁,使得Java代码能够调用Cairo库的原生函数。JNA更为简单,因为它不需要编译原生代码,而JNI则可能提供更好的性能但需要...

    Test4j使用介绍

    Test4j通过Java Native Access (JNA) 或 Java Native Interface (JNI) 与Tesseract C++库进行交互。JNA是默认方式,如果需要更高效或特定功能,可以考虑切换到JNI模式。 **6. 性能优化** 为了提高性能,可以预先...

    ZeroMQ.rar

    2. **jzmq.dll**:这是ZeroMQ的Java绑定,通常与Java Native Access (JNA) 一起使用,允许Java应用程序调用ZeroMQ的原生库。 3. **zmq-jvm16-3.1.jar** 和 **zmq-jvm17-3.1.jar**:这两个是ZeroMQ的Java版库文件,...

Global site tag (gtag.js) - Google Analytics