JNI Klasse casten geht nicht

Hi,

kurze Frage aber kann man eine JNI-Klasse nicht casten?

Habe eine C++ Physics Library per SWIG automatisch in JNI-Klassen wrappen lassen.
Eine der C++ Factory Methoden liefert je nach Parameter ein anderes Objekt zurück. Wenn ich versuche das Java-Äquivalent in die entprechende Unterklasse zu casten fällt ein „Fatal Error in 0x0000007“ oder so ähnlich.

So im Nachhinein nachgedacht macht das vielleicht auch ein bisschen Sinn, nur wie mach ich das jetzt bloß? :confused:

Beste Grüße
TMII

Direkt beim casten? Bei JNI hebelt man natürlich alles aus, aber direkt beim casten sollte eigentlich nichts schlimmes passieren. Kannst du mal ein paar relevante Zeilen posten, damit man sich das besser vorstellen kann?

So sieht das direkt in C++ geschrieben aus (offizieller Code)

b2RevoluteJointDef jointDef;
b2RevoluteJoint* joint = (b2RevoluteJoint*)myWorld->CreateJoint(&jointDef);```

Und so bei mir in Java

FrictionJointDef jdef = new FrictionJointDef();
FrictionJoint fjoint = (FrictionJoint) world.createJoint(jdef);


und ich bekomme diese Meldung (habe den Code auf dem Main-Thread getestet und bekomme jetzt auch eine richtige Fehlermeldung statt nur Fatal Error)
****java.lang.RuntimeException: java.lang.ClassCastException: com.google.fpl.liquidfun.Joint cannot be cast to com.google.fpl.liquidfun.FrictionJoint****

OK. da müßte sich jetzt ein SWIG-Experte dransetzen (ich hatte mir das nur angeschaut, und gedacht: Ah, OK, das gibt’s - aber es nie “ernsthaft” für die Verwendung in betracht gezogen). Der Einstieg wäre wohl SWIG-3.0 Documentation , denn dass “irgendein” Joint nicht zu einem FrictionJoint gecastet werden kann, ist ja klar, FALLS die konkrete Information über die Vererbungsbeziehung nicht durch SWIG durchgeschleift wird (sorry, nix konkretes…)

SWIG hat mir bisher auch mehr Zeit geraubt als es mir ersparen sollte, vom Aufsetzen von SWIG (ich kann die Linux-Tools nicht leiden die man immer manuell Platform spezifisch aufsetzen muss), bis zum rudimentären erlernen von SWIG und dem Eingeständnis dass man in SWIG wiederum sogenannte “interface”-files schreiben muss die praktisch den Header-Files gleichen und man sich frägt: Wenn ich eh nochmal alles neu schreiben muss, kann ich nicht eigentlich stattdessen gleich manuell meinen Code per JNI anbinden und bin schneller?
Schlussendlich kommt man nicht drumherum erst SWIG lernen zu müssen von der komplizierten Installation bis zur richtigen Ausführung in der Dokumentation die übrigens 1329 Kapitel(!) hat!!!
Wenn ich mir nen Bohrer kaufe, der mit einer Anleitung mit 1329 Kapiteln daher kommt, dann dreh ich die Schraube selber rein!
Eigentlich dachte ich SWIG würde unkompliziert und automatisch die C++ Library von Google in mein Java Projekt integrieren, hätte ich stattdessen alles selber gemacht wäre ich immernoch schneller gewesen als bis ich SWIG auf meinem System zum laufen gebracht hätte (kein Witz, hat 5Tage gedauert).

Wo war ich? Achja richtig: JNI und Downcasten!
Nach der Dokumentation geht das wohl nicht gerade sehr gut.
Der Punkt SWIG-3.0 Documentation gibt Workarounds an, aber sagt im Grunde nicht mehr aus als: JNI und Casten? Geht nicht!

Wie bereits gesagt: Eigentlich logisch im Nachhinein bedacht.
Denn sobald C++ ein Objekt von der Superklasse “Joint” (in meinem Beispiel) zurück gibt, kreiert JNI automatisch das Java Äquivalent (also ein Objekt der abstrakten Klasse Joint, was eigentlich keinen Sinn ergibt denn die Klasse ist nicht umsonst als abstrakt deklariert) denn das JNI weiß natürlich nicht dass das in C++ zurücjgegebene Objekt eigentlich ein FrictionJoint ist.
Entsprechend kann man auch nicht casten.

Der für mich einzige Workaround ist in diesem Fall entweder auf C++ Seite den cast durchzuführen, sodass JNI die richtige Klasse anbindet oder auf Java Seite die Factory-Methode implementieren und dann die richtige JNI-Klasse generieren und zurückgeben.
Letzteres ist leider etwas schwerer in meinem Fall da der C++ Code keinen Aufruf der Konstruktoren ermöglicht.

WENN DAS LEBEN WENIGSTENS MANCHMAL NUR EINFACHER WÄRE!

Ich danke dir Marco!

(Wofür auch immer…).

Schon fast OT: Wie gesagt, mit SWIG hatte ich mich nie wirklich beschäftigt, und … „es sieht sehr mächtig aus“ ( ← Programmierer wissen, was das bedeutet :smiley: ). Es gibt ja eine Reihe Alternativen. Auf GitHub - bytedeco/javacpp: The missing bridge between Java and native C++ sind einige aufgelistet (die, laut der Aussage dort, natürlich alle schlechter sind als javacpp (was ich aber auch noch nicht verwendet habe). Welche davon gut mit Dingen wie Factories und Vererbung klar kommt, ist aber wohl nur schwer rauszufinden…