我正在开发一个需要与C应用程序通信的Java应用程序。 C应用程序使用共享内存和mmap进行通信,我需要Java应用程序才能访问相同的内存。
我的第一次尝试涉及使用JNI调用从共享内存中检索数据,但是每个JNI调用的开销都会导致性能下降,因此我想要一种方法来访问Java中的内存并在数据检索上进行数据检索。 Java方面。
我的想法是我需要做以下事情:
这是最好的方法吗?另外,我不确定如何实际创建FileChannel以指向正确的内存位置。
答案 0 :(得分:11)
使用ByteBuffer.allocateDirect
。显然,这些缓冲区可以通过JNI层传递给可以直接访问内存的本机代码。
有关提示,请参阅this page(引用如下)。
现在,JNI代码不仅可以在Java端发现使用ByteBuffer.allocateDirect()创建的缓冲区内的本机内存空间的地址,而且可以分配自己的内存(例如,使用malloc())然后回调JVM将该内存空间包装在一个新的ByteBuffer对象中(执行此操作的JNI方法是NewDirectByteBuffer())。
答案 1 :(得分:1)
我会写一个小的C模块mmaps共享内存并使用套接字允许另一个应用程序看到那个内存(例如你的Java应用程序)
答案 2 :(得分:0)
如果你同时拥有C和Java应用程序,他们可以通过控制台流进行通信 - 对于二进制数据来说很难,但可能。我会交换共享内存以获得更多的消息传递方式 - 例如TCP / IP套接字对。
顺便问一下,传递什么样的数据以及它有多大?
答案 3 :(得分:0)
难道你不能用一些本地方法编写Java类,用C编写本机方法实现来用mmap做你想做的事。然后将其编译为本机库,并使用LD_LIBRARY_PATH将其添加到运行时。这将使您能够在没有JNI开销的情况下使用Java进行本机C调用(我认为)。
这里有一些教程:link
例如,您可以编写一个Java类,例如:
JMMap.java
public class JMMap {
public native void write(...)
}
然后针对类文件运行javah以生成类似:
的内容JMMap.h
JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject);
在.c文件中实现此功能。将其编译到库中。将其添加到LD路径,然后只需调用Java函数。
答案 4 :(得分:-2)
如果您可以将数据保存到C中的文件中,然后从Java访问该文件,那将是最好的。 AFAIK你不能以你想要使用Java的方式指向内存。