2010-02-11 7 views
7

He encontrado muchas referencias en línea (incluidas algunas sobre stackoverflow) para que JNA se use para bibliotecas C++, pero nada de lo que puedo encontrar en los documentos JNA indica que es posible. No parece haber ninguna manera de ajustar una clase de C++, en particular.Java Native Access no funciona en C++, ¿verdad?

Necesito acceso nativo para usar RTAudio, pero todas las funciones de RTAudio son funciones miembro de la clase RTAudio. Entonces, solo para confirmar, JNA no es el camino correcto.

Respuesta

9

Lo que esta pregunta es pedir how to call C++ instance methods using JNA, y es posible, pero vas a tener que hacer un trabajo. En particular, deberá escribir un contenedor que extern "C" sea cual sea la función que necesite invocar.

Para cualquier definición arbitraria type* function() puede asignar el método utilizando JNA como devolver un com.sun.jna.Pointer, pero no podrá invocar métodos en un objeto C++ desde JNA.

Una solución simple para esto sería escribir una biblioteca de interfaz de C que simplemente invoca el método en los objetos para usted ... así que si usted tiene alguna función miembro foo() que podría exportar un método C a partir de su código C++:

extern "C" void bar(type* var){ 
    var->foo(); 
} 

Obviamente, esto agregará algo de trabajo para usted ... pero sospecho que la sobrecarga para cambiar a JNI sería casi lo mismo.

JNA sólo se preocupa por la forma en que se exporta el método en el archivo DLL - y que debe ser sin decoraciones C++ (de ahí el extern "C"), por lo que puede hacer lo que necesita dentro de cualquiera de estos métodos, sin exponer métodos que llamas

En mi ejemplo anterior, esto significa que foo(), mientras esté definido dentro de la DLL, de hecho, ni siquiera tiene que estar expuesto. Como se trata de una función de C++, JNA no puede invocarla directamente, pero se puede invocar desde una función a la que JNA puede llamar, por lo que la solución propuesta funciona.

Así que, sí, puede encapsular llamadas a todas las funciones miembro (crear, operar, destruir) en una sola función y a JNA no le importará.

+0

Gran respuesta gracias.Si un método C normal crea la instancia de la clase C++ dentro del cuerpo de la función, llama a la función miembro y luego elimina el objeto, ¿puedo evitar este enlace de las funciones miembro directamente? ¿O JNA de alguna manera "sabrá" y rechazará lo que de otra manera parecería ser una función C pero que usa C++ dentro de sus cuerpos? –

+1

@carneades: necesitaba más espacio de lo que permiten los comentarios, ver mi edición en la publicación. –

+0

Gracias Mark, ¡esto funcionó a la perfección! extern "C" void rtattempt (void) { RtAudio :: RtAudio audio; std :: cout << "num dispositivos:" << audio.getDeviceCount() << std :: endl; } –

2

Probar Swig. Creará wrappers para clases de C++ por ti.

2

BridJ es un hijo espiritual de JNA que agrega un poco de soporte limitado de C++ (+ soporte completo de JNAerator). Si usted no está utilizando demasiadas plantillas que sólo podría funcionar ...

(exención de responsabilidad: Soy el autor de BridJ & JNAerator)