2011-01-12 21 views
12

Desarrollo de aplicaciones/programas en C/C++. Estoy más versado en estos dos idiomas y me encanta ser desarrollador de C++. Me pregunto cómo crear un programa Java que contenga todo mi código C++.Envoltura C/C++ dentro de Java

Quiero decir, me gustaría envolver todo mi código C++ (que ya está desarrollado) dentro de la clase Java. Pero no tengo idea de cómo hacerlo.

Por favor, publique sus respuestas o métodos/pasos para integrar C++ dentro de Java. (usando JNI es el camino, pero no pude encontrarlo en www cómo usarlo)

FYI, utilizo Eclipse IDE para desarrollar.

¿Cómo y qué paquetes debo incluir en el espacio de trabajo de mi proyecto?

+0

Su problema general no se puede resolver fácilmente; convertir cada clase de C++ de a una en clases de Java a través de JNI es bastante difícil. ¿Por qué quieres usar estas clases de C++ en Java? ¿Hay alguna razón por la que deba usar Java pero quiera la funcionalidad existente? – templatetypedef

+0

No quiero perder la funcionalidad de mi C++. Hace ciertas funciones que Java no puede hacer por sí misma y no sé mucho cómo hacerlo todo en Java. Entonces me gustaría integrar mi C++ dentro de Java. :-) :-) –

+3

"... Hace ciertas funciones que Java no puede hacer por sí mismo ..." - Sinceramente, cuestionaría esta afirmación. "No se puede hacer"? Evidencia, por favor. – duffymo

Respuesta

7

Si desea llamar a C++ desde Java, deberá usar JNI - Java Native Interface.

Tenga en cuenta que perderá algunos de los beneficios del recolector de basura, ya que no puede tratar con sus objetos C++, y su código ya no será portátil.

Tal vez sea mejor si aprende a escribir 100% Java y deja atrás C++, pero eso es solo una sugerencia.

+1

Tengo todo listo en mi C++ para recoger basura de todas las partes del código. Me sentiría muy bien si pudieras enviarme un ejemplo mínimo sobre el uso de JNI. :-) –

+0

Para eso es el tutorial en el enlace. – duffymo

+0

Lo intentaré. ¡Gracias! –

0

El módulo JNI no es una clase de Java. Es C. El uso de JNI entraña muchas restricciones y algunos entornos Java no son compatibles con JNI.

No hay apoyado manera de "envolver mi código C++ dentro de la clase de Java" (EDIT: Quiero decir, sin JNI noway pero JNI es problemático.)

Se podría investigar personalizados compilador de C++ emitir códigos de bytes de Java , pero nadie (incluirme) recomendará este enfoque.

3

Hay muchos tutoriales para hacer exactamente lo que quiere hacer. Por ejemplo, consulte: http://www.javamex.com/tutorials/jni/getting_started.shtml

También hay muchas advertencias sobre el uso de JNI. Recientemente comencé a trabajar con él (solo por diversión, en realidad), y suele ser mucho menos divertido de lo que había anticipado.

En primer lugar, usted tiene que tratar con el código críptico, tales como:

#include "test_Test.h" 

JNIEXPORT jint JNICALL Java_test_Test_getDoubled(JNIEnv *env, jclass clz, jint n) { 
    return n * 2; 
} 

En segundo lugar, tiende a restar importancia a una de las razones principales por las que el uso de Java en el primer lugar: WORA (escribe Una vez, ejecutar en cualquier lugar). Como Duffymo mencionó, también puede haber problemas con el recolector de basura, pero creo que en los últimos años, la JVM se ha vuelto bastante inteligente con respecto a la integración de JNI.

Dicho esto, para portar todo su código C++ a JNI, necesitaría refactorizar sus interfaces (y tal vez incluso hacer algunas gimnasias internas). No es imposible, pero en realidad no es recomendable. La solución ideal es simplemente volver a escribir su código en Java.

Con eso dicho, también podría "convertir" su código de C/C++ a Java programáticamente, y existen multitud de tales utilidades. Pero, por supuesto, las máquinas son más tontas que las personas y también están obligadas a cometer errores, dependiendo de cuán compleja sea su clase.

+0

¡Lo has dado increíble! ¡Intentaré esto en el fin de semana! –

5

No puede "simplemente envolverlo", tiene que escribir algo de pegamento C/C++.

Para empezar, SWIG puede hacer la mayoría de los trabajos para usted.

+0

SWIG es bueno si quieres escribir enlaces múltiples entre varios idiomas. Escribe el mapeo una vez y solo genera puertos. Pero todavía es demasiado trabajo redefinir todas las estructuras de datos para mapear todo, incluso en SWIG. Es mejor que escribir JNI. Pero hay mejores alternativas ala JNA. – chubbsondubs

1

Evitaría JNI porque es tedioso escribir, prolijo y simplemente un dolor total. En cambio, usaría la biblioteca JNA, lo que hace que la escritura de integración nativa sea tan simple.

https://github.com/twall/jna/

Buena suerte.

0

BridJ fue diseñado a propósito para eso (y es compatible con JNAerator, que analizará sus encabezados C/C++ y escupirá los enlaces de Java por usted).

Es una alternativa reciente a JNA, con soporte para C++.

13

En lugar de JNI, o JNI con un poco de asistencia desde un generador de envoltura automática como TRAGO, o incluso JNA, es posible que considerar la separación de la C/C++ y Java en procesos separados y el uso de algún tipo de IPC y/o Java Process abstracción para llamar a un programa escrito en C/C++. Este enfoque abandona el "envoltorio", por lo que en cierto sentido no es una respuesta a esta pregunta, pero por favor, lea antes de votar abajo. Creo que esta es una respuesta razonable al problema más amplio en algunos casos.

El motivo de este enfoque es que cuando llama a C/C++ directamente desde Java, , la JVM corre el riesgo de sufrir un error en el código nativo. El riesgo depende, en cierta medida, de la cantidad de código nativo que le pertenece y de cuánto enlaza con el código de un tercero (y la cantidad de acceso que tiene al código fuente de dicho código de terceros).

Me encontré con una situación en la que tuve que llamar a una biblioteca C/C++ desde Java y la biblioteca C/C++ tenía errores que causaban la falla de la JVM. No tenía el código fuente de un tercero, así que no pude arreglar el/los error (s) en el código nativo. La solución final fue llamar a un programa separado de C/C++, vinculado a la biblioteca de terceros. La aplicación Java luego hacía llamadas a muchos procesos nativos efímeros cada vez que necesitaba llamar a C/C++.

Si el código nativo tiene un problema, es posible que pueda recuperar/reintentar en Java. Si el código nativo está envuelto y llamado desde el proceso de JVM, podría eliminar toda la JVM.

Este enfoque tiene implicaciones en el rendimiento/consumo de recursos y puede no ser una buena opción para su aplicación, pero vale la pena considerarlo en ciertas situaciones.

Tener una aplicación por separado que ejerza la funcionalidad del código C/C++ es potencialmente útil como una utilidad independiente y para las pruebas. Y tener una línea de comando limpia o una interfaz IPC podría facilitar futuras integraciones con otros lenguajes.

Como otra alternativa, puede entrar en native signal handling para mitigar los riesgos para la integridad del proceso de JVM si lo desea y seguir con una solución de embalaje.

+0

Gracias por su respuesta. Bueno, mis habilidades arquitectónicas no son tan buenas ... Pero debo escribir la aplicación como mencionaste (separarlas a 2 procesos), debo considerar este consejo. Tomará tiempo para que pueda contactarte con algunas preguntas. Gracias de nuevo.. –

1

Puede escribir código C++ a través de JNI, pero no hay una asignación directa de las clases de C++ a las clases de Java. He usado JNI para solucionar problemas encontrados en el SDK de Android (específicamente, una implementación de FloatBuffer.put increíblemente lenta) y puedo terminar usándolo para algunas áreas críticas de rendimiento. Mi consejo sería usarlo con moderación y agacharse, hacer las cosas críticas de rendimiento y salir, sin hacer ninguna asignación de memoria si puede evitarlo. Además, no olvide medir su código para ver si realmente es más rápido.

Fuera de interés, ¿en qué plataforma está desarrollando? La única plataforma en la que tendría sentido envolver una gran cantidad de código C++ en una capa ligera de Java sería Android, en otras plataformas, simplemente compilar en C++ y haberlo hecho.