有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (6) 个答案

  1. # 1 楼答案

    很难回答这样一个一般性的问题。我认为最明显的区别是,使用JNI,类型转换在Java/本机边界的本机端实现,而使用JNA,类型转换在Java中实现。如果您已经对用C编程感到非常满意,并且必须自己实现一些本机代码,那么我认为JNI看起来不会太复杂。如果您是一名Java程序员,只需要调用第三方本机库,那么使用JNA可能是避免JNI可能不太明显的问题的最简单方法

    尽管我从未对任何差异进行过基准测试,但由于设计原因,我至少会假设在某些情况下,使用JNA进行类型转换的性能会比使用JNI时差。例如,当传递数组时,JNA将在每个函数调用开始时将这些数组从Java转换为本机数组,并在函数调用结束时将其转换为本机数组。使用JNI,您可以控制自己何时生成阵列的本机“视图”,可能只创建阵列的一部分视图,在几个函数调用中保留视图,最后释放视图,并决定是保留更改(可能需要复制回数据)还是放弃更改(无需复制)。我知道您可以使用内存类跨JNA的函数调用使用本机数组,但这也需要内存复制,这在JNI中可能是不必要的。这种差异可能并不相关,但如果您最初的目标是通过在本机代码中实现部分应用程序来提高应用程序性能,那么使用性能较差的桥接技术似乎不是最明显的选择

  2. # 2 楼答案

      不支持C++类的映射,所以如果使用C++库,则需要JNI包装器< /LI>
    1. 如果你需要大量的内存复制。例如,你调用一个返回大字节缓冲区的方法,你改变了其中的一些内容,然后你需要调用另一个使用这个字节缓冲区的方法。这将需要您将这个缓冲区从c复制到java,然后再从java复制回c。在这种情况下,jni将在性能上获胜,因为您可以在c中保留和修改这个缓冲区,而无需复制

    这些就是我遇到的问题。也许还有更多。但总体而言,jna和jni的性能并没有太大区别,所以无论在哪里使用jna,都要使用它

    编辑

    这个答案似乎很受欢迎。以下是一些补充:

    1. 如果需要映射C++或者COM,Oliver Chafic的创建程序是jnAuor的一个库,名为BridJ。它仍然是一个年轻的图书馆,但它有许多有趣的功能:
        < C++ > C++ C++动态调用:C++方法,创建C++对象(和java类的C++类)<李>
      • 使用泛型的简单类型映射(包括更好的指针模型)
      • 全自动充气机支架
      • 适用于Windows、Linux、MacOS X、Solaris和Android
    2. 至于内存复制,我相信JNA支持直接字节缓冲,所以可以避免内存复制

    所以,我仍然相信,只要有可能,最好使用JNA或BridJ,如果性能非常关键,最好使用jni,因为如果您需要频繁调用本机函数,性能的影响是显而易见的

  3. # 3 楼答案

    我实际上用JNI和JNA做了一些简单的基准测试

    正如其他人已经指出的,JNA是为了方便。使用JNA时,不需要编译或编写本机代码。JNA的本机库加载器也是我见过的最好/最容易使用的库加载器之一。遗憾的是,你似乎无法将其用于JNI。(这就是为什么我写了an alternative for System.loadLibrary(),它使用JNA的路径约定,支持从类路径(ie jars)无缝加载。)

    然而,JNA的性能可能比JNI差得多。我做了一个非常简单的测试,调用了一个简单的本机整数增量函数“return arg+1;”。使用jmh进行的基准测试表明,对该函数的JNI调用比JNA快15倍

    一个更“复杂”的例子显示,本机函数对一个包含4个值的整数数组求和,JNI的性能仍然是JNA的3倍。减少的优势可能是因为在JNI中访问数组的方式:我的示例创建了一些内容,并在每次求和操作中再次发布

    代码和测试结果可以在at github中找到

  4. # 4 楼答案

    顺便说一句,在我们的一个项目中,我们保留了一个非常小的JNI足迹。我们使用协议缓冲区来表示域对象,因此只有一个本机函数来连接Java和C(当然,C函数会调用一系列其他函数)

  5. # 5 楼答案

    1. 您是在几年前JNA出现之前编写代码的,或者是针对1.4版本之前的JRE
    2. 您正在使用的代码不在DLL\SO中
    3. 您正在处理与LGPL不兼容的代码

    这是我头脑中唯一能想到的,尽管我对这两种方法都不是很在行。如果你想要一个比他们提供的更好的接口,那么你可能会避免使用JNA,但是你可以用java来编写代码

  6. # 6 楼答案

    这不是一个直接的答案,我没有使用JNA的经验,但当我看到Projects Using JNA并看到SVNKit、IntelliJ IDEA、NetBeans IDE等名称时,我倾向于相信这是一个相当不错的库

    实际上,我肯定会在必要时使用JNA而不是JNI,因为它看起来确实比JNI(它有一个无聊的开发过程)简单。太糟糕了,JNA在这个时候没有发布