My aim is to pass data from a C++ process to a Java process and then to receive a result back.
I have achieved this via a named pipe but I would prefer to share the data rather than passing or copying it, assuming the access would be faster.
Initially, I thought of creating a shared segment in C++ that I could write to and read with Java, but I'm not sure if this is possible via JNI, let alone safe.
I believe it's possible in Java to allocate the memory using ByteBuffer.allocateDirect and then use GetDirectBufferAddress to access the address in C++, but if I'm correct this is for native calls within JNI and I can't get this address in my C++ process?
Lost.
Many thanks in advance.
You can share class data between Java™ Virtual Machines (JVMs) by storing it in a cache in shared memory. Sharing reduces the overall virtual storage consumption when more than one JVM shares a cache.
What is shared memory? Shared memory is the fastest interprocess communication mechanism. The operating system maps a memory segment in the address space of several processes, so that several processes can read and write in that memory segment without calling operating system functions.
Shared memory is a memory shared between two or more processes.
Processes don't share memory with other processes. Threads share memory with other threads of the same process.
If you have shared memory, for example using CreateFileMapping
(Windows) or shmget
(Unix), all you need is a native method on the Java side. Then you can create a ByteBuffer
that directly accesses the shared memory using NewDirectByteBuffer
like this:
JNIEXPORT jobject JNICALL Java_getSharedBuffer(JNIEnv* env, jobject caller) { void* myBuffer; int bufferLength;
Now you have to get a pointer to the shared memory. On Windows you would use something like this:
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
Now you can just create a ByteBuffer
that is backed by this shared memory:
// put it into a ByteBuffer so the java code can use it return env->NewDirectByteBuffer(myBuffer, bufferLength); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With