如何将C变量(JNI)存储到Java类实例

时间:2013-08-22 09:01:19

标签: java c java-native-interface

背景
我的应用程序现在已经到了瓶颈,其中最慢的部分是AES加密和解密所有数据必须通过的流。为了克服这个问题,我计划通过JNI和OpenSSL在本机代码中实现这种加密,这样我就可以利用像AES-NI和直接内存访问这样的东西(我的缓冲区已经是直接的,所以我已经可以获得指向它们的指针记忆区域)

问题
每次我需要密码或解密某些数据时,用密钥重新创建OpenSSL密码是没有意义的。如果我使用Java,我只会将Cipher实例存储为类中的字段,但由于密码是C“对象”,我不能这样做。

问题
如何将C“对象”绑定到Java类实例,以便后续调用可以使用存储的“对象”。我想这与将“对象”指针作为一个long存储到Java类中然后解除引用它有关,但是我不太确定这是完全跨平台的。

答案
必须是:

  • 简单化
  • 快速
  • 跨平台

谢谢你的时间!

2 个答案:

答案 0 :(得分:1)

由于您传递批量数据,我建议使用直接的ByteBuffer。这是一个从Java进入本机内存的窗口。一旦你写入ByteBuffer,它就已经被复制到本机内存了。从C,您可以获取地址并将其用作指向不移动的内存的指针。

如果您只需要跨操作系统,但是您使用的是基于OpenJDK的JVM,则可以使用Unsafe直接通过地址访问本机内存(就像指针一样)。我建议你把它包装在课堂上并彻底测试。

答案 1 :(得分:1)

您可以在Java Object中创建变量private int mNativeObj,以及保存本机指针的方法,如public void setNativeObject(int pointer)。在C代码中,调用CallVoidMethod()将指针保存到Java Object。您可以参考Oracle's doc