JNI

Fórumok

Van egy fizikai eszköz amit Java alkalmazásból kellene vezérelni. Ehhez kaptunk egy dll-t (device.dll). C-ben van írva, megkaptuk a függvények listáját melyeket hívni lehet.

Pl:

int __stdcall ReadSerNumber(char* SerNum);

Ahogy próbálom hívni:

public class Main {
    static {
        System.loadLibrary("device"); 
    }

    private native int ReadSerNumber(String SerNumber);

    public static void main(String[] args) {
        Main obj = new Main();
        obj.ReadSerNumber(...
    }
}

Nem igazán sikerült szerintem megértenem a JNI lényegét. Ha egy meglévő libet szeretnék felhasználni akkor is létre kell hozni a javah -val a header állományokat, és kell írnom valami c kódot hozzá, hogy működjön vagy enélkül is kellene mennie a dolognak?

Hozzászólások

Szerkesztve: 2021. 02. 11., cs – 10:20

Kukkants ra a project panama ra: https://jdk.java.net/panama/. Legenerál minden szükséges java osztályt, helpereket, stb. Elég neki odaadni a .h filet. Nyilván ez ilyen early access cucc, de majd eldöntitek hogy ez belefér-e.

JNI ahogy működik:

 * Java prototípust csinálod meg először

 * javah-hal generálsz C hearedeket

 * Pontosan a generált header szerinti függvény prototípusokat kell megvalósítani. A belépési pontok nevei a Java csomag+osztály+metódusnévből adódnak. Ez véletlenül sosem lesz épp passzentos. Ergó meglévő függvényt direktben nem érsz el JNI-n keresztül sosem.

 * A JNI belépési pontokban megírod az illesztést egy kis C kódot, ami a Java paramétereket lefordítja C-re, és meghívja az eredeti kódot.

 

Másik megoldás: JNA. https://github.com/java-native-access/jna Ez hasonlít ahhoz, amit te akarsz, ha szerencséd van, akkor nem kell JNI illesztőt csinálnod, ezzel működni fog.

Lassabb, és erőforrásigényesebb, de az esetek 99%-ára elegendő a sebessége és kicsit kezdőbarátabb megoldás a JNA.

Nem tudom mennyire elvetemült ötlet C-ben megírni a REST endpointokat és aztán azokat hívogatni Java-ból?

zászló, zászló, szív

Az előző munkahelyemen erre a célra JNA-t használtunk, sokkal kényelmesebb, mint a JNI, akkor elég jól működött. Azóta változott egy kicsit, de valami ehhez hasonlót kellett elkövetni:
https://riptutorial.com/java/example/18621/introduction-to-jna

Meg kell írni egy interface-t (figyelni kell arra, hogy a típusok nem ugyanazok, ld. byte és tsai), és arra hívva a loadLibrary-t tudod használni.