jna jni_JNA遇见JNI

本文介绍了Java Native Access(JNA)框架,作为替代JNI进行本机代码调用的一种更简单的方式。JNI的流程包括编写Java类、使用javah生成C头文件和存根实现,然后编译和加载库。而JNA则简化了这一过程,允许直接在Java中定义接口来映射本机函数,使得调用如NTLM身份验证或Windows API更加便捷。然而,JNA的性能通常比JNI慢,并且对于复杂的方法签名可能较难处理。
摘要由CSDN通过智能技术生成

jna jni

我最近偶然发现了一个不错的框架,如果您不得不使用本机代码的话,您会喜欢的。 在此框架之前,如果需要调用本机代码,则可以使用JNI 。 JNI使用了一个经过验证的但复杂且容易出错的过程。

首先,您像往常一样编写Java类。 但是对于要委派给本机代码的方法,可以使用native关键字,而不提供实现。 然后,您调用JDK提供的名为javah的可执行文件。 这将生成您的C头文件(* .h)和一个空的存根实现:您必须填补空白。 最后,您将同时编译Java和C文件。

在运行时,不要忘记使用System.loadLibrary("mylib")加载库。 请注意,您没有提供扩展名,JVM会根据您的平台(Windows上的.dll ,Linux上的.so )自动为您提供扩展名。 然后调用Java类,它将神奇地委托给您的本机代码。

由于以下原因,整个过程总是让我感到沮丧(因此,我可以想象,很多开发人员):

  • 因为我是Java开发人员,而不是C开发人员,所以我永远无法编写出色的C代码。 甚至考虑内存分配或让我自己思考函数指针都伤了我的头head
  • 如果需要更改本机Java方法签名,则必须再次运行整个过程,或者无错误地更改标头和C文件,然后再次编译所有内容。 在这种情况下,我不能强调拥有非常自动化的构建过程或适当的IDE的重要性(我倾向于前者)
  • 最后但并非最不重要的一点是,如果我无权访问源C文件怎么办? JNI无法帮助您调用Windows dll ...否则您必须编写类似代理的C文件

让人们高兴。 Java.net为您带来了解决方案。 问题的答案是Java Native Access或JNA。 现在,调用NTLM身份验证或在应用程序中显示正在运行的服务将变得轻而易举。 让我们尝试获取有关在Windows下运行的计算机的信息-抱歉,'Nix用户。

首先是要知道哪个功能可以带您到达那里:这就是MSDN库的目标。 现在,创建一个接口,最好在您将使用的DLL之后命名,并使其继承自com.sun.jna.Libray 。 它的方法必须精确映射DLL的名称和参数。 例如,假设您要显示计算机的名称。 在Windows下, kernel32.dll提供了一种名为GetComputerNameW()的方法。 因此,您的接口将具有一个名为GetComputerNameW() 。 细节中的魔鬼,您必须将MSDN中记录的每个参数映射到接口方法签名中的一个参数上。 GetComputerNameW()具有2个参数: LPTSTR (指向char缓冲区的指针)和LPDWORD (指向整数的指针)。 运行到JNA文档,Java中的映射成为char[]com.sun.jna.ptr.IntByReference

您的界面现在如下所示:

publicinterfaceKernel32extendsStdCallLibrary{

    intGetComputerNameW(char[]name,IntByReferencenumber);
    // Other method mappings
    ...
}

现在,为了访问Kernel32引用,只需使用以下代码行。 在表格下,它将通过代理将我们的接口绑定到基础实现:

Kernel32kernel32=(Kernel32)Native.loadLibrary("kernel32",Kernel32.class);

完成此操作后,每次对kernel32的GetComputerName()方法的GetComputerName()都将用我们计算机的名称填充char缓冲区。

JNA仍然存在一些缺点:

  • JNA的执行速度通常比JNI慢10倍。 它具有一些加快执行速度的技术,因此,如果您处于性能感知环境中,则可能需要使用它们。
  • 它不会使您成为专业的C程序员,因此非常复杂的方法签名将使您陷入疯狂:这项工作最困难的部分是将数据类型从C映射到Java。 这可能会让您java.lang.UnsatisfiedLinkError: Error looking up function XXX: La procédure spécifiée est introuvable因为您将看到java.lang.UnsatisfiedLinkError: Error looking up function XXX: La procédure spécifiée est introuvable经常是可java.lang.UnsatisfiedLinkError: Error looking up function XXX: La procédure spécifiée est introuvable 在这种情况下,请致电C程序员寻求帮助!

人士这个小项目提供Maven风格。 玩Java和Windows!

翻译自: https://blog.frankel.ch/jna-meets-jni/

jna jni

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值