2011-01-11 4 views
4

Ich habe folgenden JNI-Wrapper C++ Code:Wie mache ich den Aufruf der JNI-Methode nicht statisch, wenn native C++ - Objekte verwendet werden?

#include "map_container.h" 
extern "C" { 
    JNIEXPORT void JNICALL Java_com_map_Map_openMapNative(JNIEnv* env, jobject thiz, jstring path); 
}; 

static map_container* map = NULL; 

void Java_com_map_Map_openMapNative(JNIEnv* env, jobject thiz, jstring path) 
{ 
    const char* filename_utf8 = env->GetStringUTFChars(path, false); 

    if (mapview) 
    { 
    delete mapview; 
    mapview = NULL; 
    } 

    mapview = new map_container((char*)filename_utf8); 

    if (filename_utf8) 
    { 
    env->ReleaseStringUTFChars(path, filename_utf8); 
    } 
} 

und haben com.map.Map.openMapNative als statisch erklärt, was bedeutet, dass ich eine Karte zu einer Zeit betrieben werden kann. Wie ändere ich diesen C++ - Code, so dass map_container* map nicht statisch wird und zu der exakten Instanz com.map.Map Klasse gehört? map_container ist vollständig C++ - Klasse und hat keine Reflexion in Java.

Antwort

2

Ich verwende SWIG, um alle notwendigen Wrapper-Code zu generieren. Sie definieren einfach die Klassen und Funktionen, die Sie in eine Schnittstellendefinitionsdatei einfügen möchten, und lassen SWIG den gesamten benötigten C++ - und Java-Code für Sie erstellen. Sehr empfehlenswert! JNI-Code von Hand zu schreiben ist einfach viel zu langweilig und fehleranfällig. Sehen Sie die SWIG , es ist sehr einfach zu bedienen.

+0

Danke für einen tollen Link. Ich bin mir nicht sicher, ob ich SWIG benutzen werde, aber die Dokumentation enthält gute Beispiele und Erklärungen für die korrekte Umsetzung meiner Aufgabe. –

2

Wenn Sie Map.openMapNative als "static native" in der Java-Quelle deklariert haben, ist die aktuelle Deklaration irreführend, da das zweite Argument tatsächlich ein Verweis auf die Map-Klasse ist (sollte "jclass clazz" sein). jobject thiz "). Ist nicht wirklich wichtig, da Sie nicht "thiz" verwenden, und jede jclass ist ein jobject.

Die Art und Weise, wie Sie diese nicht-statische Methode erstellen, besteht darin, die "statische" von der Deklaration auf der Java-Seite zu entfernen und "thiz" zu verwenden, um auf Mitglieder der Instanz zuzugreifen.

+0

Danke, aber wie mache ich 'map_container' ein Mitglied von' thiz'? –

+0

Das Einbetten eines C++ - Objekts in ein Java-Objekt kann durch Deklarieren eines int-Felds (für 64-Bit-Zeiger) in den Java-Quellen und anschließendes Festlegen des Felds mit SetIntField erfolgen. In openMapNative würden Sie GetIntField verwenden, um den Zeiger wiederherzustellen. Der hässliche Teil befasst sich mit den Objektlebensdauern, z. Möglicherweise müssen Sie einen Finalizer auf der Java-Seite deklarieren, der eine Aufräumfunktion aufruft, die das C++ - Objekt löscht. – fadden

Verwandte Themen