Wie übergibt man eine komplexe Struktur zwischen C und Java mit JNI unter Android NDK
Ich habe eine komplexe Verteilung in den C-code auf meinem Android-Anwendung, und ich möchte, um es in den Java-Seite.
Ich habe einige Forschung bei google und stackoverflow, also ich habe die java-Klasse von meinem C-Verteilung, aber jetzt, wie man es in Java.
Ich habe festgestellt, diese Informationen, die über einen pointer in der Klasse und verwenden Sie diese auf der C-Seite :
Get the field ID : (*env)->GetFieldID(...)
Get the pointer : (*env)->GetLongField(...)
Set the pointer : (*env)->SetLongField(...)
Aber ich verstehe nicht, wie es wirklich funktioniert ...
Oben, können Sie finden, was ich gemacht habe bis jetzt ... nicht so viel !
Auf der C-Seite :
ComplexStructure Java_com_main_MainActivity_listenUDP(JNIEnv* env, jclass clazz)
{
int i,taille;
ComplexStructure myStruct;
taille = -1;
taille = recvfrom(socket, &myStruct, sizeof(ComplexStructure ), 0, &rcvAddr, &sizeOfSock);
if(taille != -1)
{
return myStruct;
}
return NULL;
}
Und auf der Java-Seite :
public void getFromUDP() {
ComplexClass myClass = new ComplexClass();
myClass = listenUDP();
}
@Override
public void run() {
initUDP();
getFromUDP();
}
public static native ComplexClass listenUDP();
public static native void initUDP();
public static native void closeUDP();
/** Load jni .so on initialization */
static {
System.loadLibrary("native-interface");
}
EDIT : ich möchte hinzufügen, dass meine Struktur ist sehr Komplex, so :
typedef struct{
TYPE_A myStructA;
TYPE_B myStructB;
TYPE_C myStructC;
TYPE_D myStructD;
}ComplexStructure;
typedef struct{
float rad;
int size;
bool isEmpty;
}TYPE_A;
typedef struct{
float rad;
bool isEmpty;
float color;
int temp;
}TYPE_B;
typedef struct{
int temp;
float rain;
bool isEmpty;
}TYPE_C;
typedef struct{
float rad;
int idPerson;
bool isOnTime;
}TYPE_D;
Sogar noch komplexer, nur ein Beispiel, um zu zeigen wie es ist !
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann nicht übergeben werden raw-C-Strukturen in Java und erwarten, dass es für die Behandlung dieser Strukturen als Klassen. Sie müssen erstellen Sie eine Klasse für deine Struktur. Ich sehe, Sie haben das bereits getan, so dass die einzige Sache, die Sie tun müssen, ist zu konvertieren, das struct in eine Instanz der Klasse.
Den code auf der Java-Seite:
wird übersetzen:
In C-code müssen laden Sie die ComplexClass mit der
env->FindClass();
Funktion. Dann erstellen Sie eine neue Instanz der Klasse (es vereinfacht die ganze Angelegenheit, wenn Sie null-parameter-Konstruktor), die Sie benötigen, zu laden, eine Konstruktor-Methode-Signatur und "invoke", die es in derenv->NewObject()
Methode. Vollständige code:Dann müssen Sie die Felder bestimmen, die von dieser Klasse verwenden
env->setXXXField();
. Wenn Sie mehrere Objekte wie Felder und möchten auch Ihnen zu schaffen, dann wiederholen Sie den obigen Vorgang für ein anderes Objekt.Dies sieht sehr kompliziert aus, aber das ist der Preis für die Verwendung von nativen C im verwalteten Java-code.
NewObject()
gibt einen lokalen Bezug, die außerhalb des Gültigkeitsbereichs und werden ungültig, sobald das erstellen von Stapel-Rahmen, das ist die native Methode gibt. Besteht die Gefahr, dass das neue Objekt wird der Müll gesammelt, bevor eine neue Referenz erstellt, die auf der Java-Seite? Betrachten Sie beispielsweise den Java-codeComplexClass cplxCls = listenUDP();
und der nativen (pseudo-)codelistenUDP() { return env->NewObject(complexClass, ctor) }
. IstcplxCls
garantiert Referenz des Objekts erstellt vonNewObject(complexClass, ctor)
?