I have a java application I need to pass some info to a C++ program. It has been suggested that I use some simple socket programming to do this. Is this the best way? If not what are the alternatives? If so, how should I go about learning about socket programming?
You could use the Java Native Interface (JNI). The JNI allows you to make calls to C libraries from Java applications. Note that JNI calls are C and not C++ calls so you will have to specify the C calling convention on your C++ functions (extern "C").
JNI has a reputation of being hard to do. It's not easy but it's certainly doable. I would advice against using sockets. Using sockets sounds like the easy way out but to me it is tantamount to opening a can of nasty worms...
You have a few options:
- Pass a file from Java to C++. This is probably simplest. It's easy to test and shouldn't require any 3rd party libraries on either end.
- Use sockets as mentioned. In C++, if you require a cross-platform solution a library such as ACE or boost will save you some heartache
- Use JNI to call from Java to C++ or vice versa. This is probably the most difficult, but most performant.
For learning sockets, a Google search for "java socket tutorial" or "c++ socket tutorial" will give you lots of information.
More information needed (but a good question).
Are these two separate programs running at the same time?
If not, and the Java program needs to call a C++ library, the JNI answer is a good solution, but it won't really work across processes.
In the case of processes, you really do need to find a way to communicate across processes...a simple solution (probably not the best, but I don't know your exact situation) would be to have a binary file that is written to and read from...just don't forget to beware of race conditions! Sockets could also work, but if your programs communicate a lot, it might be a bit of a hog on CPU power.
A simple way to do this is using standard input and output:
class MyTest {
public static void main(String... args) {
System.out.println("carpet");
}
} // Java
#include <iostream>
#include <string>
int main() {
string input;
std::getline(std::cin, input);
std::cout << "from java: " << input << std::endl; // output: carpet
} // C++
# start by piping java's output to c++'s input
$ java MyTest | ./my_receive
The options that Dave mentioned are some of the most common approaches.
As an extension to the JNI solution, you might also look at direct ByteBuffers (Java 1.4 and onward) if you have some raw data you want to share between Java and C++. The direct byte buffers allow you to allocate a buffer of some size on either the C++ or Java side and then easily access the buffer from both languages; in Java this is done through methods on the ByteBuffer object and in C++ you can obtain a pointer to the data. The ByteBuffers are handy if you have a decent amount of information to exchange and you don't want to pass it all as parameters in a JNI method.
The socket approach is probably overkill, but I'm not sure what you're specifically trying to do.
Also, if this isn't lost in the noise, use SWIG to help you if you try the JNI route. http://www.swig.org/
There's also the option of SOAP but that's probably overkill assuming you've simply got two processes on the same machine. Still I mention it for sake of completeness.
Although an answer has been accepted, a key problem here is the semantic mismatch between the two languages: assuming you have some sort of stream connection going on, how do you efficiently interchange data?
One solution I might recommend is Google Protocol Buffers. It doesn't solve the subprocess/JNI/socket issue, but what it does do is allow you a pretty efficient way to have a complex object structure transit over a stream protocol.
Remember: JNI is complicated, particularly for complex object references, but it's efficient. The most important thing is to pass data over that efficient context switch properly. GPB+JNI/Sub-Process Socket allows a single context switch to pull data over, combined with efficient codec support on both sides.