Wir betrachten wir haben eine C++ Klasse:
class iVehicle
{
public:
virtual void Run() {}; // not-pure virtual here for simplicity of a wrapper, but could be pure (see the end of the post)
virtual int GetSize() const; // we want to reuse it in Java
};
Wir wollen eine Klasse Bot
in Java erstellen, die Klasse iVehicle
im Sinne erstreckt, der den C++ Code aus iVehicle::GetSize()
und vom C bis super
aufrufen ruft ++ Sichtweise können wir die Instanzen Bot
als iVehicle*
Variablen verwenden. Das ist schwierig, da C++ keine integrierte Funktionalität für Reflektionen bietet.
Hier ist eine mögliche Lösung.
Um C++ Klasse in Java verwenden wir einen Java-Wrapper, dh generieren müssen:
class iVehicle
{
public void Run() { Native_Run(); }
public int GetSize() { return Native_GetSize(); }
private native void Native_Run();
private native int Native_GetSize();
// typecasted to pointer in C++
private int NativeObjectHolder;
// create C++ object
native static private int CreateNativeObject();
}
Die Verwendung in Java ist einfach:
class Bot extends iVehicle
{
public int GetSize()
{
if (condition) return 0;
// call C++ code
return super.GetSize();
}
}
Allerdings gibt es eine C++ Teil ist Dieser Code:
static jfieldID gNativeObjectHolderFieldID;
JNIEXPORT void JNICALL Java_com_test_iVehicle_Run(JNIEnv* env, jobject thiz)
{
int Value = env->GetIntField(thiz, gNativeObjectHolderFieldID);
iVehicle* Obj = (iVehicle*)Obj;
// todo: add checks here, for NULL and for dynamic casting
Obj->Run();
}
Der ähnliche Code ist für GetSize()
.
Dann erstellen Sie eine Instanz von Java's Bot
Sie müssen CreateNativeObject()
aufrufen und den zurückgegebenen Wert dem Feld NativeObjectHolder
zuweisen.
JNIEXPORT int JNICALL Java_com_test_iVehicle_CreateNativeObject(JNIEnv* env, jobject thiz)
{
iVehicle* Obj = new iVehicle;
return (int)Obj;
}
Also, das ist das Schema. Damit dies funktioniert, müssen Sie den Löschcode hinzufügen und C++ - Klassen analysieren, um den gesamten Klebecode zu generieren.
Hinzugefügt:
Im Fall, in dem iVehicle
eigentlich abstrakt ist, werden Sie eine nicht-abstrakte Wrapper generieren müssen, dass Sie in der Lage sind zu instanziiert:
class iVehicle
{
virtual void Run() = 0;
}
class iVehicle_Wrapper: public iVehicle
{
virtual void Run() { ERROR("Abstract method called"); };
}
Und instanziiert iVehicle_Wrapper
in CreateNativeObject()
. Vuala! Sie haben eine abstrakte C++ - Klasse in Java geerbt.
Starten Sie [hier] (http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/intro.html#wp725). Sie werden feststellen, dass der JNI-Kleber Java nicht an C++ - Klassen bindet. Dafür braucht man etwas, das um JNI herum gebaut ist.[Jace] (http://code.google.com/p/jace/wiki/Overview) ist nützlich, geht aber nicht so weit, wie du es beschrieben hast. Meine Wette ist, dass Sie nichts finden werden, das Sie vermeidet, manuell eine konkrete C++ - Klasse zu erstellen und diese zu umhüllen. –
@TomBlodget: Danke! Schlagen Sie zum Erstellen von Wrappern ein Tool wie SWIG vor oder gibt es eine andere Möglichkeit? – vvid
Schauen Sie sich auch [BridJ] (http://bridj.googlecode.com) an. –