C++和Java进程之间的共享内存

26

我的目标是将数据从C++进程传递到Java进程,然后再收到结果。

我已经通过命名管道实现了这一点,但我更希望共享数据而不是传递或复制它,因为这样可以更快地访问。

最初,我考虑在C++中创建一个共享段,以便我可以用Java写入并读取,但我不确定是否可以通过JNI实现这一点,更不用说安全性了。

我相信在Java中可以使用ByteBuffer.allocateDirect分配内存,然后使用GetDirectBufferAddress来访问C++中的地址,但如果我正确的话,这只适用于JNI内的本地调用,我无法在我的C++进程中获取这个地址?

迷茫中。

先感谢您。

2个回答

19
如果您有共享内存,例如使用CreateFileMapping(Windows)或shmget(Unix),则您只需要在Java端使用本地方法。然后,您可以使用NewDirectByteBuffer创建一个ByteBuffer,它可以直接访问共享内存,如下所示:
JNIEXPORT jobject JNICALL Java_getSharedBuffer(JNIEnv* env, jobject caller) {
    void* myBuffer;
    int bufferLength;

现在你需要获取一个指向共享内存的指针。在Windows上,你可以使用以下方法:
    bufferLength = 1024; // assuming your buffer is 1024 bytes big
    HANDLE mem = OpenFileMapping(FILE_MAP_READ, // assuming you only want to read
           false, "MyBuffer"); // assuming your file mapping is called "MyBuffer"
    myBuffer = MapViewOfFile(mem, FILE_MAP_READ, 0, 0, 0);
    // don't forget to do UnmapViewOfFile when you're finished

现在你可以创建一个由这个共享内存支持的ByteBuffer
    // put it into a ByteBuffer so the java code can use it
    return env->NewDirectByteBuffer(myBuffer, bufferLength);
}

@cam79请将此标记为答案。已测试并且可行。 - sweisgerber.dev

4

您是否考虑使用0MQ?它支持JavaC++,且更加可靠。如果您想在Java中进行共享内存,则需要通过JNI来实现,根据我上次查看的信息,没有其他方法。

如果您选择这条路线,则需要通过JNI进行操作。尽管我找到的解决方案只适用于Windows系统,可能并不适用于您的情况。


1
你在Android上有使用0MQ的第一手经验吗? - sweisgerber.dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接