2009-01-20 9 views
18

Tengo una aplicación Java Necesito pasar información a un programa C++. Se ha sugerido que use algunos simples programas de socket para hacer esto. Es esta la mejor manera? ¿Si no, cuales son las alternativas? Si es así, ¿cómo debo aprender sobre la programación de socket?¿Cuál es la mejor manera de pasar información de Java a C++?

Respuesta

16

Usted tiene algunas opciones:

  • pasar un archivo de Java a C++. Esto es probablemente el más simple. Es fácil de probar y no debería requerir ninguna biblioteca de terceros en ninguno de los extremos.
  • Use enchufes como se menciona. En C++, si necesita una solución multiplataforma, una biblioteca como ACE o boost le ahorrará algunos dolores de cabeza
  • Use JNI para llamar de Java a C++ o viceversa. Este es probablemente el más difícil, pero el más eficiente.

Para sockets de aprendizaje, una búsqueda en Google de "java socket tutorial" o "c++ socket tutorial" le dará un montón de información.

1

Puede utilizar la interfaz nativa de Java (JNI). El JNI le permite hacer llamadas a bibliotecas C desde aplicaciones Java. Tenga en cuenta que las llamadas JNI son llamadas C y no C++, por lo que tendrá que especificar la convención de llamadas C en sus funciones C++ (extern "C").

JNI tiene una reputación de ser difícil de hacer. No es fácil, pero ciertamente es factible. Yo recomendaría no usar enchufes. Uso de las tomas suena como el camino más fácil, pero para mí es equivalente a abrir una lata de gusanos repugnantes ...

+0

He oído hablar de SWIG, pero nunca lo he usado. ¿Es más fácil que JNI? ¿Alguien sabe? – OscarRyz

0

Se necesita más información (pero es una buena pregunta).

¿Se están ejecutando estos dos programas por separado al mismo tiempo?

Si no es así, y el programa Java necesita llamar a una biblioteca C++, la respuesta JNI es una buena solución, pero realmente no funcionará en todos los procesos.

En el caso de los procesos, realmente necesita encontrar una forma de comunicarse entre procesos ... una solución simple (probablemente no la mejor, pero no sé cuál es su situación exacta) sería tener un archivo binario archivo que se escribe y se lee de ... ¡simplemente no se olvide de tener cuidado con las condiciones de carrera! Los zócalos también podrían funcionar, pero si sus programas se comunican mucho, podría ser un poco difícil para la potencia de la CPU.

6

Una forma sencilla de hacer esto es mediante la entrada y salida estándar:

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 
1

Las opciones que Dave mencionados son algunos de los enfoques más comunes.

Como una extensión de la solución JNI, también puede ver ByteBuffers directos (Java 1.4 y posterior) si tiene algunos datos sin procesar que desea compartir entre Java y C++. Los búferes de byte directo le permiten asignar un búfer de cierto tamaño en el lado C++ o Java y luego acceder fácilmente al búfer desde ambos idiomas; en Java esto se hace a través de métodos en el objeto ByteBuffer y en C++ puede obtener un puntero a los datos. Los ByteBuffers son útiles si tiene una cantidad decente de información para intercambiar y no quiere pasarlo todo como parámetros en un método JNI.

El enfoque socket es probablemente overkill, pero no estoy seguro de lo que está tratando específicamente de hacer.

0

También existe la opción de SOAP, pero eso es probablemente excesivo suponiendo que simplemente tiene dos procesos en la misma máquina. Todavía lo menciono para mayor completitud.

4

Aunque se ha aceptado una respuesta, un problema clave aquí es la falta de correspondencia semántica entre los dos idiomas: suponiendo que tiene algún tipo de conexión de transmisión, ¿cómo intercambia datos de manera eficiente?

Una solución que podría recomendar es Google Protocol Buffers. No resuelve el problema del subproceso/JNI/socket, pero lo que sí hace es permitirle una forma bastante eficiente de hacer que una estructura de objeto compleja transite sobre un protocolo de flujo.

Recuerde: JNI es complicado, especialmente para referencias a objetos complejos, pero es eficiente. Lo más importante es pasar los datos sobre ese interruptor de contexto eficiente correctamente. El socket GPB + JNI/Subprocesamiento permite que un solo conmutador de contexto extraiga datos, combinado con un soporte eficiente de códec en ambos lados.

Cuestiones relacionadas