当前位置: 首页 > 面试题库 >

使用JNI而不是JNA来调用本机代码?

雷逸仙
2023-03-14
问题内容

与JNI相比,JNA似乎更易于调用本机代码。在什么情况下,您将在JNA上使用JNI?


问题答案:
  1. JNA不支持c 类的映射,因此,如果您使用的是c 库,则需要一个jni包装器
  2. 如果需要大量内存复制。例如,您调用一个返回大字节缓冲区的方法,对其中的内容进行更改,然后需要调用使用此字节缓冲区的另一种方法。这将需要您将该缓冲区从c复制到java,然后再将其从java复制回到c。在这种情况下,jni将赢得性能,因为您可以在c中保留和修改此缓冲区,而无需复制。

这些是我遇到的问题。也许还有更多。但总体而言,jna和jni之间的性能并没有什么不同,因此无论您在哪里可以使用JNA,都可以使用它。

编辑

这个答案似乎很受欢迎。因此,这里有一些补充:

  1. 如果需要映射C ++或COM,则JNAerator的创建者Oliver Chafic有一个名为BridJ的库。它仍然是一个年轻的图书馆,但是它具有许多有趣的功能
    • 动态C / C / COM互操作:调用C 方法,创建C 对象(以及Java的子类C 类!)
    • 善于使用泛型的简单类型映射(包括指针更好的模型)
    • 全面的JNAerator支持
    • 适用于Windows,Linux,MacOS X,Solaris,Android
  2. 至于内存复制,我相信JNA支持直接ByteBuffer,因此可以避免内存复制。

因此,我仍然相信,只要性能至关重要,最好尽可能使用JNA或BridJ,并恢复为jni,因为如果需要频繁调用本机函数,则性能会受到明显影响。



 类似资料:
  • 我想用Java将一个文件放入Windows中的回收站。以便用户能够还原它。

  • 我试图使用JNA调用这个本机Windows方法: 但是我真的很难理解我应该用什么作为Java方面的参数。使用JNA,您应该创建与本机C结构匹配的Java类,我已经成功地使用了WinAPI的其他部分。 据我所知,LPDIRECTSOUND是一个“指向DirectSound结构的长指针”的typedef,LPUNKNOWN是一个“指向未知的长指针”的typedef? 我在dsound.h中找到了本机结

  • 这可能是一个真正的新手问题,但我正在编写一个Android应用程序,它需要使用一个用C编写的.so库。该.so由几个类组成,是通用C语言,而不是JNI语言。 除了JNI之外,有没有办法从AndroidJava应用程序调用C函数?我所看到的关于JNI的一切都表明,您必须重写本机代码以特定于JNI,如果只给您一个. so,那真是太不方便了。 在Android 4.0.3中,从java应用程序调用本机函

  • 线程“main”java.lang.UnsatifiedLinkError:查找函数“StartConector”时出错:找不到指定的过程。在com.sun.jna.function.(function.java:179)在com.sun.jna.nativelibrary.getfunction(nativelibrary.java:350)在com.sun.jna.nativelibrary.

  • 我想并行化对不可重入的本机库(DLL)的调用。两个线程应该并行调用本机函数。我想使用JNA访问DLL。锁不是解决方案,因为这不是并行性。 我至今的想法是: > 线程池,其中线程将每个代理实例保存到加载了本机的DLL。loadLibrary() 线程池,每个线程将一个代理实例保存到具有不同名称的自己的物理DLL。每个都加载了N个ative.load库()。(它可能只有在相同的库接口,可以加载多个DL

  • 问题内容: 我正在尝试编写一些通过JNA执行等待的代码(例如,通过调用Kernel32函数WaitForSingleObject),但是如果调用Thread.interrupt(),我也希望等待完成。我假设Java使用Event对象之类的东西来实现中断;有什么办法可以从Java获取事件,以便在对WaitForMultipleObjects的调用中使用它?或者如果线程被中断,还有其他方法可以安排等待