【发布时间】:2009-01-20 21:38:45
【问题描述】:
我有一个 java 应用程序,我需要将一些信息传递给 C++ 程序。有人建议我使用一些简单的套接字编程来做到这一点。这是最好的方法吗?如果不是,有什么替代方案?如果是这样,我应该如何学习套接字编程?
【问题讨论】:
标签: java c++ sockets cross-platform
我有一个 java 应用程序,我需要将一些信息传递给 C++ 程序。有人建议我使用一些简单的套接字编程来做到这一点。这是最好的方法吗?如果不是,有什么替代方案?如果是这样,我应该如何学习套接字编程?
【问题讨论】:
标签: java c++ sockets cross-platform
你有几个选择:
对于学习套接字,Google 搜索 "java socket tutorial" 或 "c++ socket tutorial" 将为您提供大量信息。
【讨论】:
一个简单的方法是使用标准输入和输出:
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
【讨论】:
虽然答案已被接受,但这里的一个关键问题是两种语言之间的语义不匹配:假设您正在进行某种流连接,您如何有效地交换数据?
我可能推荐的一种解决方案是 Google Protocol Buffers。它不能解决子进程/JNI/socket 问题,但它的作用是让您以一种非常有效的方式让复杂的对象结构通过流协议进行传输。
记住:JNI 很复杂,特别是对于复杂的对象引用,但它很有效。最重要的是正确地通过有效的上下文切换传递数据。 GPB+JNI/Sub-Process Socket 允许单个上下文切换来拉取数据,并结合双方的高效编解码器支持。
【讨论】:
您可以使用 Java 本机接口 (JNI)。 JNI 允许您从 Java 应用程序调用 C 库。请注意,JNI 调用是 C 而不是 C++ 调用,因此您必须在 C++ 函数(外部“C”)上指定 C 调用约定。
JNI 以难做而著称。这并不容易,但肯定是可行的。我建议不要使用套接字。使用套接字听起来很简单,但对我来说这无异于打开一罐讨厌的蠕虫......
【讨论】:
Dave 提到的选项是一些最常见的方法。
作为 JNI 解决方案的扩展,如果您想要在 Java 和 C++ 之间共享一些原始数据,您还可以查看直接 ByteBuffers(Java 1.4 及更高版本)。直接字节缓冲区允许您在 C++ 或 Java 端分配一定大小的缓冲区,然后轻松地从两种语言访问缓冲区;在 Java 中,这是通过 ByteBuffer 对象上的方法完成的,而在 C++ 中,您可以获得指向数据的指针。如果您有大量信息要交换并且您不想在 JNI 方法中将其全部作为参数传递,那么 ByteBuffers 会很方便。
套接字方法可能矫枉过正,但我不确定您具体要做什么。
【讨论】:
需要更多信息(但这是个好问题)。
这两个独立的程序是否同时运行?
如果不是,并且 Java 程序需要调用 C++ 库,JNI 答案是一个很好的解决方案,但它不会真正跨进程工作。
在进程的情况下,你确实需要找到一种跨进程通信的方法......一个简单的解决方案(可能不是最好的,但我不知道你的确切情况)是有一个二进制文件这是写入和读取的......只是不要忘记提防竞争条件!套接字也可以工作,但如果您的程序进行大量通信,则可能会占用 CPU 资源。
【讨论】:
此外,如果您没有忘记这一点,请在尝试 JNI 路线时使用 SWIG 来帮助您。 http://www.swig.org/
【讨论】:
还有SOAP 的选项,但假设您只是在同一台机器上有两个进程,这可能有点过头了。为了完整起见,我仍然提到它。
【讨论】: