Komplizierte C++-Library an Java anbinden

Aus dem Frust-Thread in ein eigenes Thema verschoben:


Versuche gerade auf Windows ein Projekt zu Stande zu bringen und bin schier am verzweifeln. Die Bibliothek ist in C++ geschrieben aber unkompiliert und dann auch noch für Linux, also benötige ich eine Windows-Hilfslibrary, aber die ist auch nicht kompiliert und auch ein Linuxprojekt, benötige eine weitere Hilfslibrary aber die ist auch nicht kompiliert und auch ein ursprüngliches Linuxprojekt. Zum kompilieren wird eine weitere Hilfslibrary benötigt…

Mal Hand aufs Herz. Ich arbeite seit Tagen Non-Stop und hab mich mit dem eigentlichen Problem noch nicht einmal beschäftigt.
Jetzt möchte ich die DLLs meinem Java Code hinzufügen weil ich kein Bock mehr auf den C++ Rotz habe, aber wer hätte das gedacht, für JNA benötige ich jetzt Maven und Cmake und leckt mich doch alle am Arsch.

Bis zum letzten Satz lag mir noch ein: „Gibt’s die DLL nicht in der Maven Central? :clown_face:“ auf der Zunge. (Wir Java Devs sind schon verwöhnt…).

Um was für eine Lib geht’s denn?

Die Leutz von OpenJDK: Panama suchen noch Leute, die ihre bisherigen Ergebnisse ausprobieren und Feedback geben. (Ja, das auf CUDA anzuwenden liegt auf meiner TODO-Liste - wird höchste Zeit…).

Es geht um ein g2o, wirst du denke ich nicht kennen. Ist ein Graphen Optimierungsalgorithmus. Schweres Zeugs, wenn man nicht gerade seine Doktorarbeit danach widmet.
Wir Java Devs sind extrem verwöhnt. Wenn wir irgendeine Funktionalität brauchen ist die in 2 Minuten in unser Projekt eingebunden und auf alle Plattformen verteilt.

Apropo, Maven kann denn JNAerator nicht kompilieren. Der ist im übrigen in Java geschrieben muss aber trotzdem selber über Maven kompiliert werden :cold_face: Das ist das Problem wenn für das Projekt 25 verschiedene Tools verwendet werden, da muss nur eins anecken.

Ist Panama denn bereits in irgendeiner Weise brauchbar? Bin nicht in der Stimmung JNI zu verwenden und hatte eigentlich gehofft möglichst einfach irgendwie die Java Bindings aufsetzen zu können jetzt wo ich endlich die .dlls dafür habe und jetzt wo ich den JNAerator nicht kompiliert bekomme bleibt wohl nur sowas?

1 „Gefällt mir“

Nun, natürlich „kenne“ ich das nicht im speziellen, aber Optimierung, Graphen und anderes „schweres Zeug“ kann ja ganz interessant sein (im examples/simple_optimize.cpp tauchte eben der Name „Levenberg“ auf, und ich nehme an, dass das der gleiche Herr ist, dessen Name im LevenbergMarquardtOptimizer von Apache Math steckt, mit dem ich am Samstag ein bißchen meinen Spaß hatte…)

Beim JNAerator bin ich nicht so sicher … also, der Olivier Chafik (den ich tatsächlich vor ~8 Jahren mal persönlich in Paris getroffen habe … tsss) hat mit JNAerator und BridJ und den OpenCL-Sachen und seinen anderen Libs schon viel gemacht, aber … einiges davon schien (oberflächlich betrachtet) etwas „ad hoc“ erstellt zu sein, und wird jetzt anscheinend auch nicht weitergepflegt :confused:

Panama ist, wie angedeutet, gerade auf dem Weg in die Öffentlichkeit. Der Haupt-Maintainer hatte mich angeschrieben, ob ich nicht mal versuchen will, CUDA da durchlaufen zu lassen. Aber das ganze ist schon sehr auf Linux ausgerichtet, und ich müßte erstmal einen lohnenden Brocken Zeit investieren, um das ganze lokal (in einer VM) aufzusetzen und mich da reinzufräsen.

(Paradoxerweise kann ich mich im Moment nicht in die Tools zur automatischen JNI-Generierung und DLL-Anbindung reinfräsen, weil ich … händisch JNI-Code für JCuda schreibe :roll_eyes: Eigentlich hab’ ich da auch einen Codegenerator, aber der ist weeeit weg von etwas benutzbarem, und die existierenden Strukturen unter der Haube von JCuda machen es ohnehin schwer, da auf was komplett neues zu setzen… Kompatibilität zwischen der Versionen finde ich schon wichtig)

Wie auch immer:

Im Moment ist für Java->Native-Anbindungen soweit ich weiß GitHub - bytedeco/javacpp: The missing bridge between Java and native C++ das „Mittel der Wahl“, aber wirklich viel damit gemacht habe ich auch noch nicht - nur ein bißchen experimentiert. Interessanterweise ist der Maintainer davon (Samuel Audet) auch sehr in Panama involviert.

Kam heute rein: http://jdk.java.net/panama/

Ach, sehr cool. Danke fürs teilen!! Aber leider nicht für Windows, meine Hoffnungen wurden zerstört.

Arbeite gerade mit JavaCPP wie von dir empfohlen. Sind zumindest interessante Einblicke die du da offenbart hast. Ist besser als SWIG und viel besser als JNA aber vollbringt halt auch keine Magie, eine Menge Arbeit bleibt weiterhin beim Programmierer hängen und einfach ist es auch nicht wenn man es nicht kann.

Habe im Moment einige Probleme die Bibliothek auf C++ Seite richtig aufzusetzen. Ständig irgendwelche Fehler hier und da und sonst wo ist plötzlich alles nicht mehr funktionstüchtig…

Deswegen bin ich an einen von vielen Scheidepunkten meine Zeit und Arbeit auf Panama und Linux oder weiter auf C++ und JavaCPP zu konzentrieren.
Auf Linux hätte ich ehrlich gesagt von Anfang an setzen sollen, wenn ich sehe wie viele Projekte in C++ sich praktisch nur um Linux drehen - da wundert es mich schon dass es überhaupt C++Programme für Windows gibt.

Ui, eine „Empfehlung“ war JavaCPP so gesehen nicht (mangels eigener „fundierter“ Erfahrung). Aber wenn ich heute vor so einer Aufgabe stünde, wäre das zumindest mein „first shot“: Es deckt schon SEHR viele (auch moderne) C++ -Libs ab, und wird aktiv gepflegt, von jemandem, der auch in Panama dabei ist.

Wenn du so kämpfst ist das vermutlich wirklich eine C++-Library - also eine, die auch C++ -Schnittstellen hat?! „Normalerweise“ werden Libs ja oft auf eine C-Schnittstelle runtergebrochen, für maximale Kompatibilität. Also, wenn man wirklich sowas hat wie

float compute(std::vector<float> data) { ... }

ist’s halt ein Krampf, das nach Java zu mappen, auf allen technischen Ebenen. Aber nicht nur das: So eine Schnittstelle wäre nichtmal für die Kommunikation „innerhalb von C++“ geeignet: Wenn sie von einer Lib stammt, die mit einem Compiler compiliert wurde, und in einer Anwendung verwendet werden soll, die mit dem anderen Compiler compiliert wird, dann haben die im Zweifel schlicht inkompatible vector-Implementierungen. (Unter Windows gibt’s das Problem ja nicht - da gibt’s eh nur MS Visual C :roll_eyes: ).

Auf jeden Fall gibt es viele gute Gründe, warum sowas dann meistens auf ein

float compute(float *data, size_t length)

runtergebrochen wird.

Apropos size_t, was ist das denn überhaupt? Ach, damit fang’ ich jetzt gar nicht erst an :wink: Wir Java-Programmierer sind schon sehr verwöhnt :wink:

Kurzes Update, ich habs bis heute nicht hinbekommen die C++ Dateien anzubinden. Hab mir eine einfach Schnittstelle in C++ geschrieben um die nötigen Funktionen in primitive Methoden zu bündeln.

  • JavaCPP stellte sich Anfangs als vielversprechend heraus, hat dann aber leider beim kompilieren seiner selbst erstellten Java als auch C++ Klassen versagt.
  • SWIG konnte am Anfang Garnichts aber mit den einfach gebündelten Funktionen kam es dann doch klar und hat mir entsprechend C++ und Java Dateien erstellt.

-> Die C++ Datei ins Projekt eingebunden, exportiert, zum Java Projekt hinzugefügt uuuund InvocationTargetException.
Könnte - sorry - kotzen.

Kann man das genauer beschreiben? Wie gesagt, bin nicht wirklich „drin“, aber neugierig… und fühl’ mich nach der „„Empfehlung““" jetzt so „verantwortlich“ :worried:

Also JavaCPP benötigt wohl mehrere Programme um auf Windows korrekt zu laufen.
Die müssen jeweils kompiliert werden und benötigen sowohl fürs kompilieren als auch für die korrekte Funktionalität weitere Programme die…

Exception in thread "brain" java.lang.StackOverflowError

Warum da jetzt Extra Programme gebraucht werden kann ich nicht nachvollziehen oder ob das mein Problem überhaupt lösen würde. Aber ich hab meinen Rechner praktisch bereits so gegen die Wand gefahren damit, dass mir einfach die Puste ausgeht das noch weiter mit zu machen.

Aber wenn er zum Beispiel die Java JavaCPP Datei (A) parst um daraus die eigentliche Java Datei (B) aus der C++ header Datei © zu erstellen, dann findet er beim kompilieren (B) nicht die darin vererbte erste Java Klasse (A) die sich natürlich immernoch im gleichen Ordner befindet.
Und der Visual Studio 17 Compiler kommt nicht mit den generierten C++ Dateien klar, wirft viele Warnungen, kompiliert nix und JCPP stürzt folgend ab.
Die genaue Ursache kannte ich jetzt nicht.

Bin absolut kein Fan von SWIG. SWIG ist nur für Leute die eine C++ Library schreiben und bei jeder Code Änderung automatisch Bindings in alle möglichen anderen Sprachen bereitstellen wollen. Aus Usersicht ist das System aber sinnfrei, weil man muss die Binding Logik immernoch selber schreiben in SWIG. Wenn man also nur eine Sprache braucht, lohnt sich der Mehraufwand meines erachtens nur bedingt.
SWIG kommt nicht mit Arrays oder Strings klar, sei angemerkt.

Da ich jetzt aber einen Großteil der Berechnungsmanagementlogik in C++ schreibe bin ich wohl zum beschriebenen Entwickler der Library gewechselt…

Inzwischen gibt es early-access-builds auch für Windows: Projekt Panama - Native Libraries direkt aus Java ansprechen