JNI -> Inhalt dll zugreifen

Unripe

Neues Mitglied
Heyho,

ich hab eine Frage bezüglich des Java Native Interfaces. Ich habe eine c++ dll, die mehrere Klassen enthält. Verschiedene Arbeiten innerhalb meines Programms müssen von einigen Methoden aus einigen der Klassen übernommen werden. Vorwiegend, weil ich keine Ahnung habe wie die Klassen implementiert sind, ich das Ergebnis aber brauche.

Gibt es eine Möglichkeit in Java es ähnlich wie z.B. in C# zu machen? Bei dem nach

Using xyz.dll;

direkt auf den Inhalt zugegriffen werden kann und sogar die Klassen instanziiert werden können?
 
woho ... da bringst du aber JNI und JNA ganz schön durcheinander ..

um es vielleicht etwas weiter auszuführen ...

java selbst ist eigentlich ein in sich geschlossenes system ... und dieses system hat genau eine definierte schnittstelle "nach außen" : JNI - Java Native Interface
diese schnittstelle gibt ganz klar namenskonventionen und einige andere parameter vor wie man java und native libs koppeln kann ...

einer dieser parameter ist C ... und zwar NUR C ... kein C++ ... und erst recht kein C# ... sondern nur reines C ...
eine objekt orientierte C++ lib kann man also so nicht direkte 1zu1 mit JNI koppeln ... sondern muss den C++-code in C-code wrapen ... sich also von der OOP-verarbeitung lösen und imperativ programmieren ...

das sieht dann so aus das eine C-funktion einen ganz bestimmten namen und ganz bestimmte parameter haben muss damit eine java-methode diese funktion callen kann ...

andersrum gilt das genau so : es gibt einen fest definierten weg wie man von einer C-funktion eine java-methode callen muss ... es geht nur genau so und nicht anders ...

oft wird es so gemacht das die JNI-lib in C implementiert wird und eine schnittstelle zur eigentlichen lib herstellt ... da man C und C++ leichter koppeln kann ...


weiterhin gibt es noch eine möglichkeit um mit einer C-lib direkt zu arbeiten wenn diese bekannt ist : JNA - Java Native Access ...
der trick liegt hier darin das JNA eigentlich nur eine JNI-lib ist die nach "außen" bestimmte schnittstellen bereitstellt um jede standard-C-lib direkt an diese zu koppeln ... man spart sich also das manuelle selbst schreiben einer wraper-lib ... das übernimmt JNA größten teils ...

was allerdings überhaupt nicht geht ist C# ... denn C# ... oder besser : DotNET ist vergleichbar mit java ... es ist eine virtuelle sprache die ebenfalls eine laufzeitumgebung benötigt (das DotNET runtime framework) um korrekt zu arbeiten ...

es gibt zwar lösungen JNI mit C# zu koppeln ... jedoch sind viele davon kostenpflichtig ... wesshalb meist von C# abgeraten wird ...

das ganze ist etwas komplex ... und bedarf viel zeit ...


ich dreh den spies aber erstmal um ...

1) von welcher seite aus willst du mit welcher arbeiten ?
willst du über JNI/JNA eine externe native-lib einbinden und mit dieser in java arbeiten ... oder willst du von C aus irgendwas mit java machen ? (letzteres stell ich mir weit schwerer vor) ...

2) welche kenntnisse hast du über das jeweilige gegenüber ? gibt es standard-schnittstellen oder muss man sich seinen eigenen weg "reinhacken" ?

3) wozu das ganze überhaupt ? es ist zwar richtig das native-code performanter ist und für einige aufgaben einfach notwendig ... aber meist verliert man durch die JNI-brdige sehr viel performance ... und wenn man etwas in der jeweiligen sprache (java oder C) direkt implementieren kann ... ist dies immer vorzuziehen ...
 
Dann versuch ich mal deine Fragen zu beantworten 🙂.

1) Ich würde gern, bzw. ich wollte, mit Java auf eine .dll-Bibliothek zugreifen, um die Methoden von einigen Klassen innerhalb der Bibliothek zu nutzen. Ziel des Projekts ist es, eine Api zu implementieren mit dem bestimmte Byte-basierte Datei-Typen geparst und ausgewertet werden können. Da ich aber nicht die Zeit habe, mich mit dem kompletten Aufbau der Hashtable eben jener Files auseinander zu setzen, wollte ich eine Bibliothek nutzen, die bereits die jeweiligen Methoden implementiert hat. Damit hätte ich mir den Aufwand erspart, mich darin auch noch einarbeiten zu müssen.

2) Ich bin Eclipse-Entwickler, habe in dem Rahmen allerdings noch nicht mit JNI/JNA gearbeitet. Ich entwickel vorwiegend Eclipse Plug-Ins, je nach Kundenanforderung. Mit C will ich prinzipell nichts tun. Reicht mir schon, ständig Code-Generatoren für den Kram schreiben zu müssen ^^. Die .dll enthält 10 Klassen mit ihren jeweiligen Methoden.

3) Steht unter 1). Hab jetzt eine alternative gefunden und von dem Entwickler der Bibliothek die Sourcen bekommen. Trotzdem würde es mich interessieren, ob es totzdem eine Möglichkeit gegeben hätte. Der Teil von C# kam daher, dass ich gesehen habe, dass man in C# mit
Code:
using Lib.LibPath;
eine Bibliothek einbinden kann und dann direkt auf die jeweiligen Klassen zugreifen und sie intanziieren kann. So als ob die Klassen selbst im Workspace vorhanden sind.
 
gut ... die idee ist klar .. du willst ne lib nutzen um mit bestimmten daten arbeiten zu können ... soweit ist die idee ja nicht neu

das problem ist halt das du eine C++ lib hast und diese so nicht einfach mit java ansprechen kannst

da du den source hast wäre natürlich eine portierung möglich ... ob es dir den aufwand wert ist musst du selbst entscheiden ... aber vieles dürfte sich in java abbilden lassen

auch ein weg wäre wie erwähnt eine JNI-wraper-lib die die aufrufe die an sie gestellt werden an die lib delegiert ... das erfordert aber C kenntnisse

eine weitere möglichkeit bietet dir JNA ... damit kann man "normale" libs direkt ansprechen ... JNA kümmert sich dabei dann um die umsetzung der daten ... ist aber auch ein thema was man nicht mal eben in 10 minuten macht ... da gehört schon einiges dazu ...

ich kenne mich mit dem thema leider auch nicht genug aus um dir direkt helfen zu können ... sicherlich hilfreich wäre es wenn du (wenn möglich) mal die gewünschte lib verlinkst das man sich das mal ansehen kann ... vielleicht gibt die DOC genug her um was mit JNA zu bauen

das größte problem dürfte wohl eher sein das man mit JNI/JNA in dem sinne nicht direkt in C++-OOP mit einer lib kommunizieren kann ... man also doch noch etwas mehr drum herum tun muss als wenn man z.b. eine C++ anwendung hat und in diese die lib einbinden würde ...

mir persönlich beritet es einfach kopfzerbrechen das du davon redest das in der lib auch OOP verwendet wird ... also mit klassen und objekten und so ... da müsste man mal in den source gucken wie weit man da mit java kommt ...
 
Um das ganze nochmal (soweit ich es verstanden habe) zusammenzufassen: Da du von Java aus nicht die Klassen der Lib nutzen kannst, wird eine Möglichkeit sein: Du schreibst eine Methode wie
Java:
public static native ReturnValue computeThisStuff(InputData data);
die du dann mit JNI ausführst, und die intern die eigentliche, C++-seitige Arbeit macht

Dann gäbe es noch JNA, was ich selbst noch nicht verwendet habe, und bei dem ich aus dem Stegreif nicht weiß, wie es mit C++-Klassen umgehen kann.

Ansonsten gibt's noch https://code.google.com/p/bridj/ , was die "ultimative" Lösung sein könnte/sollte/wird? aber was noch etwas ... "experimentell" ist.
 
weil ich mir das C++-OOP beispiel auf der gelinkten seite gerade ansehe ...

Code:
class MyClass {
	public:
	    MyClass();
	    ~MyClass();
	    virtual void virtualMethod(int i, float f);
	    void normalMethod(int i);
};
void getSomeCount(int* countOut);
//...
void test() {
    int count;
    getSomeCount(&count);
    MyClass t;
    t.virtualMethod(count, 0.5f);
}

DAS wird dir das genick brechen ...

da du ja was von klassen gefaselt hast gehe ich davon aus das die lib in etwa so aussehen wird wie der obige code ...
das problem ist nun das du mit JNA KEINEN zugriff auf die klasse hast ... sondern nur auf z.b. getSomeCount() und test() ... aber NICHT auf virtualMethod() und normalMethod() ...
und auch mit JNI (also einer selbst geschriebenen lib wie es Marco angedeutet hat) müsstest du sowas wie in test() steht implementieren um mit der klasse zu arbeiten ...

und genau das habe ich gemeint als ich sagte das man nur "prozeduales C" verwenden kann ...
klar könntest du in diesem beispiel mit JNA direkt auf die prozedualen funktionen zugreifen ... aber die klasse wäre dir immer noch verwehrt ...

das ist leider das problem wenn man java und C koppeln will ... es gibt einschränkungen ...


und das ist auch der grund warum man C# nicht direkt koppeln kann ... da dort genau wie in java ALLES in solchen klassen steht ... die dazu noch vom DotNET ausgeführt werden müssen da sich MS hier nur bedingt an den C-standard gehalten hat ...
 

Zurück
Oben