C# týden Slevový týden - Březen
Využij náš slevový týden a získej až 30 % bodů navíc zdarma! Zároveň také probíhá C# týden se slevou na e-learning až 80 %
Hledáme fulltime programátora do ITnetwork týmu -100% homeoffice, 100% časově flexibilní #bezdeadlinu Mám zájem!

5. diel - JNI - Príklad v Eclipse bez Makefile as reťazcom

V minulom tutoriále o Java Native Interface sme si ukázali, ako vytvoriť JNI aplikáciu v IDE Eclipse CDI a použili sme k tomu Makefile.

Dnes si budeme pomáhať trochu aj príkazovým riadkom. Nie každý chce totiž v Eclipse používať Makefile. Opätovne je projekt takmer identický ako v predchádzajúcich dvoch dieloch. A aby sme to trochu okorenili, nebudeme využívať len primitívne dátové typy, ale pohráme si aj so STRING.

Osnova postupu

  1. Vytvoríme Java projekt vrátane spúšťací triedy (.java) a skompilujeme pre Java8, 7, 6, ... ( .class)
  2. Vytvoríme hlavičkový súbor (* .h) a prekonvertuje do C / C ++ projektu
  3. Z header filu (hlavičkového súboru) vytvoríme source file (zdrojový súbor * .c)
  4. Nastavíme kompilátor a linker v Eclipse CDT IDE
  5. Vykonáme kompiláciu a linkovanie danej zdieľané knižnice (* .dll)
  6. Upravíme spúšťacie Java triedu, aby sme načítali natívne knižnicu a zavoláme natívne metódy z Javy

1 - Tvorba a kompilácie Java projektu

Ako prvý krok samozrejme skontrolujeme perspektívu, musí byť nastavená Java. Ďalej vytvoríme Java projekt, ktorý si nejako pomenujeme. Vytvoríme spúšťací triedu bez balíčka a doplníme telo spúšťacie metódy + navrhneme natívne metódy. Program spustíme a dole v konzole si skontrolujeme kontrolný výstup. Je to identické z predchádzajúcej kapitolou.

public class ProgramString {
    native void metodaTest();
    native String posliString(String str);
    public static void main (String [] args) {
        System.out.println("Testovací výpis z Javy");
    }
}

Čo danej metódy vlastne robia? Prvá metóda je jasná (pozri. Minulej kapitoly). Druhá metóda má návratový typ String, čo znamená, že natívny metóda nám prenesie hodnotu typu String z natívne časti programu do interpretované časti programu a zároveň je String aj parameter interpretované časti, ktorý sa prenesie do natívne. Iba vykonáme zmenu toho reťazca. Prakticky je to triviálne časť.

Java trieda s natívnymi metódami

2 - Vytvorenie hlavičkového súboru a konverzie projektu

(Pre Java 9,8,7,6, ...) Pretože nám Eclipse neumožňuje v Project exploreru zobraziť * .class (skompilovanej Java triedy) a my potrebujeme vyrobiť cez "javah" hlavičkový súbor, tak budeme musieť spustiť navigator, ktorý nám zobrazí * .class súbory.

nastavenie navigátora

V navigátora klikneme na adresár \ bin \ a za pomocou klávesovej skratky CTRL + ALT + T sa nám v Eclipse zobrazí terminál. Jedná sa o obyčajný command prompt, dostupný v Eclipse od verzie 3.7. Vďaka nemu vygenerujeme za pomocou príkazu súbor * .h. Cez Popup menu vyvoláme refresh projektu a všimneme si vzniku súboru ProgramString.h (header file * .h) v adresári \ bin \. Tento súbor okamžite presunieme do adresára \ src \.

javah -jni ProgramString

Pre Java 10,11 [18.9], 12 [19.3], ...: V adresári \ src \ spustíme terminal a zadáme tento príkaz.

javac -h . ProgramString.java
Vytvorenie hlavičkového súboru
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Ako ďalšie vykonáme konverziu z Java Projektu na C / C ++ projekt. K tomu samozrejme nestačí len zmeniť perspektívu. Konverziu vykonáme podľa obrázku. Označíme projekt, ktorý chceme skonvertovať, a vyvoláme Popup okno -> new -> other. Objaví sa dialógové okno New, vyberieme C / C ++ -> zvolíme Convert to a C / C ++ Project. Ďalej nastavíme vlastnosti projektu. Zvolíme projekt a vyberieme C Projekt, zvolíme Shared Library (zdieľaná knižnica) project a typ kompilátora v našom prípade MinGW. Postup je takmer identický ako v predchádzajúcom článku.

Zmena projektu

Môžeme si všimnúť zmien Project exploreru v projekte. Projekt sa prekonvertovať. Samozrejme automaticky došlo k zmene perspektívy na C / C ++. Po konverzii projektu nám vzniknú nejaké error, ale zatiaľ si ich nevšímajte, čoskoro sa ich zbavíme.

3 - Vytvorenie zdrojového súboru C / C ++

Teraz si do adresára \ src \, kde je umiestnený zdrojový kód Java aplikácie a hlavičkový súbor, vytvoríme zdrojový kód pre knižnicu "ProgramString.c". Označíme daný adresár a opäť vyvoláme Popup okno. Vyberieme cestu New -> File -> a objaví sa nám opäť dialógové okno. Zvolíme adresár, kam sa má vytvoriť, a do File name vyplníme názov.

Vytvorenie zdrojového súboru C / C ++

Akonáhle vytvoríme zdrojový súbor * .ca vložíme tento kód, ktorý uložíme, tak by mali samy zmiznúť spomínané error. Doplníme hlavičky metód (funkcií) deklaráciami a vyplníme tela daných funkcií.

#include <jni.h>
#include <stdio.h>
#include "ProgramString.h"
#include "string.h"
JNIEXPORT void JNICALL Java_ProgramString_metodaTest(JNIEnv *env, jobject obj){
    printf("Testovaci Vypis z Nativni casti JNI Programu");
}

JNIEXPORT jstring JNICALL Java_ProgramString_posliString(JNIEnv *env, jobject obj, jstring str){
    // zpracujeme vstupni retezec
    const char *retezec = (*env)->GetStringUTFChars(env, str, 0);
    printf("Zde je vlozeny retezec : %s\n", retezec);
    //  POZOR pouze 256 znaku
    char veta [256];
    //  vlozeni retezce do pole charu
    strcpy(veta,"Ahoj jak se mas ?");
    // slouceni retezcu v C-cku
    strcat(veta,retezec);
    jstring vystup = (*env)->NewStringUTF(env,veta);
    return vystup;
}

Teraz si trochu preberieme čo sme vykonali. Prvý funkciu kvôli jednoduchosti preskočíme. Druhá funkcia už zaujímavejšie. C-čko samotnej nepodporuje String, takže je nutné ho za pomoci JNI metódy (funkcia) "GetStringUTFChars ()" previesť na pole char. Tu je zoznam všetkých JNI fukcií podporovaných v JNI API. Syntax C nebudem rozoberať. Ďalšie funkcie "NewStringUTF ()" vytvára String, ktorý potom presunieme do interpretované časti, je to návratová hodnota našej funkcie.

Vypísanie zdrojového kódu

4 - Nastavenie kompilátora a linker

Teraz nás čaká najnudnejší, ale aj najdôležitejšia časť. Prevedieme nastavenie kompilátora / linker v Eclipse IDE. Klikneme (označíme) projekt a stlačíme ALT + ENTER. V strome si vyberieme C / C ++ Build -> Settings -> a tu v Configuration nastavíme All configurations.

nastavenie projektu

Teraz vykonáme nastavenie kompilátora. V strome v záložke Tool Settings vyberieme možnosť GCC C Compiler a do Command vložíme kompilátor pre 64bit x86_64-w64-mingw32-gcc. Skontrolujeme parametre v All options -O3 -Wall -c -fmessage-length=0. Pravdepodobne v defaultu budete mať - O0, takže sa presuňte do Optimization a nastavte -O3. Inak ak by sme nezastavili PATH k jni.ha jni_md.h, do PATH by sme tu kompilátora museli v možnosti Includes (-I) danej paths nastaviť.

nastavenie kompilácie

Ďalej vykonáme nastavenie linker. V strome sa prepneme na MinGW Linker a do Command opäť vložíme kompilátor pre 64bit x86_64-w64-mingw32-gcc. Do možnosti Miscellaneous doplníme do Linker flags tento reťazec -Wl,--add-stdcall-alias a potom sa späť prepneme do MinGW C Linker. Tu uvidíme upravený All options. (-Shared ... je tam defaultne a označuje tvorbu * .dll).

nastavenie linker

Zvolíme Apply a OK. Tým máme nastavený kompilátor aj builder.

5 - Kompilácia do * .dll

Čaká nás teda prevedenie tzv. "Buildu". Najskôr však vykonáme vyčistenie projektu. V menu zvolíme možnosť Project -> Clean ... -> označíme projekt a vypneme automatický build.

Potom klikneme na známe kladivko a build sa vykoná. Zdieľaná knižnica vznikne v adresári Debug, odkiaľ ju budeme v Java aplikácii načítať.

prevedenie buildu

6 - Úprava Java triedy a volanie natívne metódy

Po úspešnom zbuildování * .dll knižnice sa vrátime do Javy. Prepneme perspektívu a zobrazíme si zdrojový kód spúšťací triedy v Jave. Najskôr vykoná načítanie knižnice a potom zavoláme natívne metódy.

public class ProgramString {
    static {
        try {
            System.loadLibrary("libProjektJNIEclipse");
            System.out.println("Nactena knihovna                                libProjektJNIEclipse.dll");
        }
        catch(UnsatisfiedLinkError e){
            System.err.println("Nelze nacist knihovnu                           libProjektJNIEclipse.dll");
            System.err.println(e.getMessage());
        }
    }
    native void metodaTest();
    native String posliString(String str);
    public static void main(String[] args) {
        System.out.println("Testovaci vypis z JAVY ");
        ProgramString program = new ProgramString();
        program.metodaTest();
        String s = "Isaac Asimov";
        System.out.println("Zde je vystup : " +program.posliString(s));
    }
}


Nastavenie Java triedy pre volanie native metód

Pred samotným spustením Java triedy je v IDE nutné opäť projekt vyčistiť. (Project -> Clean). Opätovne je nutné JVM informovať, kde danú * .dll hľadať a toho docielime nastavením v konfigurátore spustení. Hore v menu zvolíme Run -> Run configurations ... a prevedieme nastavenie. V strome si nájdeme spúšťací triedu prepneme záložku Arguments -> VM argument, kam vložíme -Djava.library.path=Debug. Potom klikneme na Apply a Run a uvidíme výsledok.

Spustenie JNI projektu

Využívať v kóde * .dll umiestnenou v adresári Debug nie je moc chytré. Každým spúšťaním prebieha kompilácie a štruktúra adresára Debug sa pokazí a prestane fungovať. Preto odporúčam vytvoriť nový adresár, napr. "Dll", a do neho knižnicu nakopírovať. Pri spustení cez IDE je vhodné upraviť VM argument -Djava.library.path=dll. Všetko by malo bežať v poriadku. Ak aplikáciu spúšťame z príkazového riadku cez IDE v konzolu alebo priamo cez command prompt, nesmieme zabudnúť, že keď spustím z adresára \ bin \, v tomto adresári sa adresár \ dll \ nenachádza a preto je nutné povedať JVM nech hľadá adresár \ dll \ o úroveň vyššie, priamo v roote projektu.

testovacie výpis

To je pre zatiaľ všetko, základná kostra riešenia bola ukázaná a jemné detaily rôznych dátových typov, objektov, pointer vs. referencie, vlákien, apod., to už bude na vás.


 

Stiahnuť

Stiahnuté 8x (74 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

 

Článok pre vás napísal Robert Michalovič
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Programuji převážně v Javě SE,EE a trochu nativním C a CUDA. více viz.https://cz.linkedin.com/in/robert-michalovic
Predchádzajúci článok
JNI - Príklad v Eclipse s Makefile
Všetky články v sekcii
JNI - Java Native Interface
Miniatúra
Nasledujúci článok
JNI - Príklad v Eclipse s C ++
Aktivity (1)

 

 

Komentáre

Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!