My app is written in Java. There is a C++ library I need to utilize. I don't want to use JNI.
60 times a second, the C++ app needs to send the Java app 10MB of data; and the Java app needs to send the C++ app 10 MB of data.
Both apps are running on the same machine; the OS is either Linux or Mac OS X.
What is the most efficient way to do this? (At the moment, I'm considering TCPIP ports; but in C++, I can do memory mapping -- can I do something similar in Java?)
Thanks!
Java Native Access (JNA) is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface (JNI). JNA's design aims to provide native access in a natural way with a minimum of effort. Unlike JNI, no boilerplate or generated glue code is required.
It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.
Native Image can be used to implement low-level system operations in Java and make them available via JNI Invocation API to Java code executing on a standard JVM.
JNIEXPORT is used to make native functions appear in the dynamic table of the built binary (*. so file). They can be set to "hidden" or "default" (more info here). If these functions are not in the dynamic table, JNI will not be able to find the functions to call them so the RegisterNatives call will fail at runtime.
Yes, Java has memory-mapped files with the NIO framework.
If you're trying to avoid JNI because you didn't want to write stubs, you can also interface with C++ code (at least ones that are extern "C"
) using JNA. For best performance, use direct mapping (concrete classes with native
methods, not a mapped interface)---see documentation for more details. :-)
Using mapped files is a way of hand-rolling a highly optimized rpc. You might consider starting with a web service talking over local sockets, using MTOM for attaching the data, or just dropping it into a file. Then you could measure the performance. If the data was a problem, you could then use mapping.
Note that there are some odd restrictions on this that make your code sensitive to whether it is running on Windows or not. On Windows, you can't delete something that is open.
I should point out that I have done exactly what you are proposing here. It has a control channel on a socket, and the data is shared via a file that is mmapped in C++ (or the Windows equivalent) and NIO mapped in Java. It works. I've never measured maximum throughput, though.
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