2012-12-13 13 views
5

Sto cercando di imparare le basi di Android NDK ma sono bloccato quando devo usarlo con una classe C++.Utilizzare una semplice classe C++ in Android NDK

Capisco come usarlo con una semplice funzione, ma cosa dovrei fare per essere in grado di manipolare i campi ei metodi di una classe C++?

che sto cercando di farlo con questa semplice C++ classe:

#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(); 
} 

ho cercato di trovare i campioni, ma nulla finora ... Forse non sto usando le parole chiave giuste

* AGGIORNAMENTO *

ho creato un wrapper Java per il C++ classe Point e aggiunto al C++ metodi di file JNI. Il codice è il seguente:

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 
} 

adesso sto stucked con la funzione nativeSymetrique, si dice che non posso convertire il 'punto' a 'jlong'. Qualcuno può aiutarmi su questo? Grazie

* UPDATE 2 *

SWIG risolto i miei problemi, non c'è bisogno di scrivere a mano gli involucri e sembra essere una buona scelta per i grandi librerie.

+0

buona domanda, se puoi usare qualcosa da "main()" allora puoi anche scrivere alcune funzioni in main che chiamano funzioni di classe, è un modo pessimo ma forse ti aiuterà :) –

+0

usi JNI? Dov'è il wrapper JNI nel tuo codice? – dilix

+0

Sì, ho intenzione di usare JNI ma questo codice è solo una semplice classe C++. Mi chiedo dove e come dovrei mettere JNI con quel codice – Fr4nz

risposta

-2

Come ho detto nel mio secondo aggiornamento, SWIG era la soluzione perfetta per le mie esigenze.

+0

Una cosa carina con Internet, è facile trovare le cose ora usando parole chiave (come 'SWIG') – Fr4nz

0

È possibile manipolare con il codice C come si desidera e passare \ restituire valori tramite JNI, è possibile trovare campioni JNI in Androidndk/samples - helloJni.

Ad esempio:

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. 
} 
+0

So che devo usare JNI, ho letto quegli esempi ma che dire delle classi C++ e JNI? Stai dicendo che dovrò scrivere una funzione JNI per ogni metodo della mia classe Point? E dovrò creare una classe simile (Point) sul lato Java con il metodo nativo? – Fr4nz

+0

Vuoi passare oggetti da java a C++? Controlla questa risposta http: // StackOverflow.it/questions/4468276/how-to-pass-java-class-istanza-come-un-parametro-a-jni-metodo e google può aiutare con objec di passaggio in JNI =) – dilix

+0

In realtà da C++ a Java – Fr4nz

1

Dai un'occhiata alla JNA.

JNI ha lo scopo di accedere a classi/oggetti Java da C. Il che significa che JNI fornisce funzioni C per l'accesso a JVM. Ma non c'è alcun modo viceversa: accedere alle strutture C (classi C++) da JVM. Java non ha tali metodi. Quindi, se vuoi avere una "riflessione di classe" tra C++ e Java, l'unica cosa che puoi fare è avere la classe sul lato Java e una serie di chiamate JNI C per accedere, modificare e chiamare metodi sull'oggetto Java. I metodi nativi JNI sul lato Java non sono utili per te, perché gli unici parametri che può assumere (dentro o fuori) possono essere di nuovo solo oggetti Java (o primitive o matrici). Semplicemente non c'è modo di passare strutture/oggetti C (++) al lato Java.

+0

Grazie per la risposta, darò un'occhiata a JNA – Fr4nz

+0

Secondo questo post http://stackoverflow.com/questions/1556421/use-jni-instead-of-jna-to-call-native-code JNA non è adatto per il mio uso a causa di C++ – Fr4nz

+0

JNA è il più vicino che puoi ottenere accesso agli oggetti nativi da Java. JNI non fornisce nulla, nemmeno Java in sé. Quindi se JNA è inutilizzabile per te, allora il secondo paragrafo, e in particolare l'ultima frase, è la mia risposta. –