当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用JNI而不是JNA来调用本机代码?》经验,为你挑选了5个好方法。

与JNI相比,JNA似乎更容易调用本机代码.在什么情况下你会使用JNI而不是JNA?



1> Denis Tulski..:

    JNA不支持c ++类的映射,因此如果你使用的是c ++库,则需要一个jni包装器

    如果你需要大量的内存复制.例如,您调用一个返回大字节缓冲区的方法,更改其中的某些内容,然后需要调用另一个使用此字节缓冲区的方法.这将要求您将此缓冲区从c复制到java,然后将其从java复制回c.在这种情况下,jni将在性能上获胜,因为您可以在c中保留和修改此缓冲区,而无需复制.

这些是我遇到的问题.也许还有更多.但总的来说,jna和jni之间的性能并没有那么不同,所以无论你在哪里使用JNA,都要使用它.

编辑

这个答案似乎很受欢迎.所以这里有一些补充:

    如果你需要映射C++或COM,那么JNAerator的创建者Oliver Chafic就有一个名为BridJ的库.它仍然是一个年轻的图书馆,但它有许多有趣的特点:

    动态C/C++/COM互操作:调用C++方法,创建C++对象(以及Java的子类C++类!)

    直接类型映射,充分利用泛型(包括更好的指针模型)

    完整的JNAerator支持

    适用于Windows,Linux,MacOS X,Solaris,Android

    至于内存复制,我相信JNA支持直接ByteBuffers,因此可以避免内存复制.

因此,我仍然相信,只要有可能,最好使用JNA或BridJ,如果性能至关重要,则恢复为jni,因为如果需要经常调用本机函数,性能损失是显而易见的.


我不同意,JNA有很多开销.虽然它的便利性非常值得在非时间关键代码中使用
我建议在使用BridJ进行Android项目之前要谨慎,直接从其[下载页面](https://code.google.com/p/bridj/wiki/Download#Android)中引用:"BridJ部分在Android上运行/ arm模拟器(使用SDK),甚至__甚至可能在实际设备上(未经测试).__"

2> jarnbjo..:

回答这样一个普遍的问题很难.我认为最明显的区别是,对于JNI,类型转换是在Java /本机边界的本机端实现的,而对于JNA,类型转换是用Java实现的.如果你已经对使用C语言编程感到很舒服并且必须自己实现一些本机代码,我会认为JNI似乎不会太复杂.如果您是Java程序员并且只需要调用第三方本机库,那么使用JNA可能是避免JNI可能不那么明显问题的最简单方法.

虽然我从来没有对任何差异进行基准测试,但我会因为设计,至少假设在某些情况下使用JNA的类型转换将比使用JNI更糟糕.例如,当传递数组时,JNA会在每个函数调用开始时将这些从Java转换为本机,并在函数调用结束时返回.使用JNI,您可以在生成数组的本机"视图"时控制自己,可能只创建数组的一部分视图,保持多个函数调用的视图,最后释放视图并决定是否需要保持更改(可能需要复制数据)或放弃更改(不需要复制).我知道你可以使用Memory类在JNA的函数调用中使用本机数组,但是这也需要内存复制,这对于JNI来说可能是不必要的.差异可能并不重要,但如果您的最初目标是通过在本机代码中实现部分应用程序性能来提高应用程序性能,则使用性能较差的桥接技术似乎不是最明显的选择.



3> stonemetal..:

    您在几年前编写代码之前有JNA或者目标是1.4之前的JRE.

    您正在使用的代码不在DLL\SO中.

    您正在处理与LGPL不兼容的代码.

这只是我能想到的,尽管我不是一个沉重的用户.如果你想要一个比他们提供的接口更好的接口,你似乎也可以避免使用JNA,但你可以在java中编写代码.


我不同意2 - 将静态库转换为动态库很容易.看到我的问题abput it http://stackoverflow.com/questions/845183/convert-static-windows-library-to-dll
从JNA 4.0开始,JNA在LGPL 2.1和Apache License 2.0下均获得了双重许可,您可以选择自己决定

4> Ustaman Sang..:

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


因此,我们没有方法调用,而是传递消息.我在JNI和JNA以及BridJ上投入了相当多的时间,但很快,他们都有点太可怕了.

5> Pascal Thive..:

这不是一个直接的答案,我没有JNA的经验,但是,当我查看使用JNA的项目并看到像SVNKit,IntelliJ IDEA,NetBeans IDE等名称时,我倾向于认为它是一个相当不错的库.

实际上,我当然认为我必须使用JNA而不是JNI,因为它确实看起来比JNI(它有一个无聊的开发过程)简单.太糟糕了,JNA此时尚未发布.

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有