Utilizar una clase simple de C ++ en Android NDK
Estoy tratando de aprender los conceptos básicos de Android NDK, pero estoy estancado cuando tengo que usarlo con una clase de C + +.
Entiendo cómo usarlo con una función simple, pero ¿qué debo hacer para poder manipular los campos y los métodos de una clase de C ++?
- Un proyecto ndk simple usando la biblioteca de Eigen y jni
- El mejor enfoque para cargar múltiples bibliotecas nativas en la aplicación para Android
- ¿Cómo hago que el método JNI no llame estático cuando se usan objetos nativos de C ++?
- Ciclo de vida de actividad de Android y ciclo de código nativo de JNI
- No se puede iniciar cygpath en android
Estoy tratando de hacerlo con esta simple clase de C ++:
#include <cstdlib> #include <jni.h> using namespace std; class Point { int x, y; // coordonnées du point public: Point() { this->x = 0; this->y = 0; } Point(int x, int y) { this->x = x; this->y = y; } int getX() const { return x; } int getY() const { return y; } Point symetrique() const { return Point(-x, -y); } bool operator ==(const Point &p) const { return this->x == p.getX() && this->y == p.getY(); } }; extern "C" { JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__ (JNIEnv *, jobject); JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__II (JNIEnv *, jobject, jint, jint); JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetX (JNIEnv *, jobject, jlong); JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetY (JNIEnv *, jobject, jlong); JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_nativeSymetrique (JNIEnv *, jobject, jlong); }; JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__(JNIEnv* env, jobject thiz) { return (jlong)(new Point()); } JNIEXPORT jlong JNICALL Java_com_example_jnipoint_JPoint_createPoint__II(JNIEnv* env, jobject thiz, jint x, jint y) { return (jlong)(new Point(x, y)); } JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetX(JNIEnv* env, jobject thiz, jlong nativePointer) { return ((Point*)nativePointer)->getX(); } JNIEXPORT jint JNICALL Java_com_example_jnipoint_JPoint_nativeGetY(JNIEnv* env, jobject thiz, jlong nativePointer) { return ((Point*)nativePointer)->getY(); } jlong Java_com_example_jnipoint_JPoint_nativeSymetrique(JNIEnv* env, jobject thiz, jlong nativePointer) { return ((Point*)nativePointer)->symetrique(); }
He intentado encontrar muestras, pero nada hasta el momento … Tal vez no estoy usando las palabras clave adecuadas
* UPDATE *
Creé un envoltorio de Java para la clase de punto de C ++ y agregado a los métodos del archivo de C ++ JNI. El código es el siguiente:
public class JPoint { private long nativePointer; public JPoint() { nativePointer = createPoint(); } public JPoint(int x, int y) { nativePointer = createPoint(x, y); } public int getX() { return nativeGetX(nativePointer); } public int getY() { return nativeGetY(nativePointer); } public JPoint symetrique() { JPoint tmp = new JPoint(); tmp.nativePointer = nativeSymetrique(nativePointer); return tmp; } // TODO /*public boolean equals(Object o) { return nativeEquals(o); }*/ private native long createPoint(); // Void constructor private native long createPoint(int x, int y); private native int nativeGetX(long nativePointer); private native int nativeGetY(long nativePointer); private native long nativeSymetrique(long nativePointer); //private native boolean nativeEquals(Object p); TODO }
Ahora mismo estoy atascado con la función nativeSymetrique, dice que no puedo convertir 'Point' a 'jlong'. Puede alguien ayudarme con esto ? Gracias
* UPDATE 2 *
SWIG resolvió mis problemas, usted no tiene que handwrite los envolturas y parece ser una buena opción para bibliotecas grandes.
- C JNI bloquea toda la aplicación de Android
- Gradle de Android, libs nativas para diferentes arquitecturas
- OpenCV para Android: ejemplo simple para convertir la imagen a escala de grises
- Extraer código de archivo .aar Android
- FindClass de cualquier hilo en Android JNI
- ¿Qué es JNI Graphics o cómo usarlo?
- Se produjo un error al agregar a la tabla ref de matrices JNI fijada (1024 entradas)
- Android: Calling System.loadLibrary () hace que el proceso muera
Echa un vistazo a JNA .
JNI está destinado a acceder a Java clases / objetos de C. Lo que significa que JNI le da funciones C para acceder a JVM. Pero no hay manera viceversa: acceder a estructuras C (clases C ++) desde JVM. Java no tiene tales métodos. Por lo tanto, si desea tener una "reflexión de clase" entre C ++ y Java, lo único que puede hacer es tener la clase en Java y un conjunto de llamadas JNI C para acceder, modificar y llamar a métodos en el objeto Java. Los métodos nativos de JNI en Java no son útiles para ti, porque los únicos parámetros que puede tomar (dentro o fuera) pueden ser sólo objetos Java (o primitivas o arrays). Simplemente no hay manera de pasar C (++) estructuras / objetos al lado de Java.
Usted puede manipular con su código C como desee y pasar \ valores de retorno a través de JNI, puede encontrar muestras JNI en androidndk / samples – helloJni.
Por ejemplo:
JNIEXPORT jfloat JNICALL Java_com_opengl_glworld_GLWorldRenderer_changeCurrentArea(JNIEnv *env, jobject obj, jfloat curArea) { area = curArea; return area; // here you can execude you C code, you can access to methods of class, // or method that use your classes. }
Como dije en mi segunda actualización, SWIG fue el complemento perfecto para mis necesidades.