IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

7. diel - JNI - Primitívne dátové typy

V minulom tutoriále o Java Native Interface sme si vyskúšali pokročilejšie príklad s reťazcami a C ++. V dnešnom dieli sa budeme venovať primitívnym dátovým typom.

Primitívne dátové typy

V predchádzajúcich dieloch sme si ukázali funkčné postupy vytvárajúce * .dll. Teraz si vyberte, ktorý vám vyhovuje, a vyskúšajte si rôzne primitívne dátové typy, ktoré tu budú zverejnené. Nie je to nijak zložité, keď existuje vzorový príklad. Tu je zoznam všetkých primitívnych dátových typov dostupných ako v Jave, Cčku, tak aj v natívnej časti (JNI).

JAVA typy JNI typy C typy JNI Veľkosť (bit)
boolean jboolean neobsahuje 8 (unsigned)
byte jbyte neobsahuje 8
char jchar char 16 (unsigned)
short jshort short 16
int jint int 32
long jlong long 64
float jfloat float 32
double jdouble double 64
void void void 0
true JNI_TRUE 1 -
false JNI_FALSE 0 -
Opis metód je celkom jednoduchý.
public class DatoveTypyPrimitivni {
    static {
        //... načteme dll
    }
    private native void vypisBoolean(boolean hodnota);
    private native boolean ziskejBoolean();
    private native void vypisByte(byte hodnota);
    private native byte ziskejByte();
    private native void vypisZnak(char znak);
    private native char ziskejZnak();
    private native void nastavShort(short hodnota);
    private native short ziskejShort();
    private native void nastavInt(int hodnota);
    private native int ziskejInt();
    private native void nastavLont(long hodnota);
    private native long ziskejLong();
    private native void nastavFloat(float hodnota);
    private native float ziskejFloat();
    private native void nastavDouble(double hodnota);
    private native double ziskejDouble();
    // Konzolovy vypis JNI metod probehne az na konci celeho naseho programu
    public static void main(String args []){
        System.out.println("Start Programu");
        DatoveTypyPrimitivni program = new DatoveTypyPrimitivni();
        program.vypisBoolean(false);
        System.out.println("Zde je hodnota z JNI : "+program.ziskejBoolean());
        program.vypisByte((byte)77);
        System.out.println("Ziskej hodnotu z Byte z JNI : "+program.ziskejByte());
        program.vypisZnak('Z');
        System.out.println("Ziskej Znak z JNI : "+program.ziskejZnak());
        short hodnota = 14563;
        program.nastavShort(hodnota);
        System.out.println("Ziskej short z JNI : "+program.ziskejShort());
        program.nastavInt(12312345);
        System.out.println("Ziskej int z JNI : "+program.ziskejInt());
        long hodnotaLong = (long)674843456;
        program.nastavLont(hodnotaLong);
        System.out.println("Ziskej long z JNI : "+program.ziskejLong());
        float hodnotaFloat = (float) 4565.35967;
        program.nastavFloat(hodnotaFloat);
        System.out.println("Ziskej float z JNI : "+program.ziskejFloat());
        double hodnotaDouble = (double)45456465.45994;
        program.nastavDouble(hodnotaDouble);
        System.out.println("Ziskej double z JNI : "+program.ziskejDouble());
        System.out.println("Konec Programu");
    }
}

Tu je vygenerovaný header file. Pomenovaný "primitivni.h".

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class DatoveTypyPrimitivni */

#ifndef _Included_DatoveTypyPrimitivni
#define _Included_DatoveTypyPrimitivni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     DatoveTypyPrimitivni
 * Method:    vypisBoolean
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisBoolean
  (JNIEnv *, jobject, jboolean);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejBoolean
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_DatoveTypyPrimitivni_ziskejBoolean
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    vypisByte
 * Signature: (B)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisByte
  (JNIEnv *, jobject, jbyte);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejByte
 * Signature: ()B
 */
JNIEXPORT jbyte JNICALL Java_DatoveTypyPrimitivni_ziskejByte
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    vypisZnak
 * Signature: (C)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisZnak
  (JNIEnv *, jobject, jchar);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejZnak
 * Signature: ()C
 */
JNIEXPORT jchar JNICALL Java_DatoveTypyPrimitivni_ziskejZnak
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    nastavShort
 * Signature: (S)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavShort
  (JNIEnv *, jobject, jshort);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejShort
 * Signature: ()S
 */
JNIEXPORT jshort JNICALL Java_DatoveTypyPrimitivni_ziskejShort
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    nastavInt
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavInt
  (JNIEnv *, jobject, jint);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejInt
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_DatoveTypyPrimitivni_ziskejInt
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    nastavLont
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavLont
  (JNIEnv *, jobject, jlong);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejLong
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_DatoveTypyPrimitivni_ziskejLong
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    nastavFloat
 * Signature: (F)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavFloat
  (JNIEnv *, jobject, jfloat);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejFloat
 * Signature: ()F
 */
JNIEXPORT jfloat JNICALL Java_DatoveTypyPrimitivni_ziskejFloat
  (JNIEnv *, jobject);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    nastavDouble
 * Signature: (D)V
 */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavDouble
  (JNIEnv *, jobject, jdouble);

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejDouble
 * Signature: ()D
 */
JNIEXPORT jdouble JNICALL Java_DatoveTypyPrimitivni_ziskejDouble
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Teraz si konečne preberieme čo znamená opis v header file pri jednotlivých metód. napr .:

/*
 * Class:     DatoveTypyPrimitivni
 * Method:    vypisBoolean
 * Signature: (Z)V
 */
  • Class: DatoveTypyPri­mitivni - Tu je to jasné, meno zdrojovej triedy, v ktorej sa metóda nachádza
  • Method: vypisBoolean - opäť úplne jasné, jedná sa o meno metódy
  • Signature: (Z) V - toto je najzaujímavejšia časť, špecifikuje jej vstupné parametre a návratový typ metódy. V našom konkrétnom prípade je metóda typu void a teda návratový parameter je "V" a vstupný parameter je boolean "(Z)"
/*
 * Class:     DatoveTypyPrimitivni
 * Method:    ziskejFloat
 * Signature: ()F
 */
  • Class: DatoveTypyPri­mitivni - meno zdrojové triedy, v ktorej sa metóda nachádza
  • Method: ziskejFloat - jedná sa o meno metódy
  • Signature: () F - V tomto konkrétnom prípade je návratový typ typu Float "F" a nemá žiadny vstupný parameter "()"
Java typy označenie typu
boolean Z
char C
byte B
short S
int Aj
long J
float F
double D
void V
Je pochopiteľné, že toto je len základný popis v prípade jedného parametra. V prípade metód s viacerými parametrami s primitívnymi dátovými typmi je riešením ich kombinácie. Sami vidíte, že návrh od programátorov JNI je veľmi logický.
native int vystupInt2(int hodnota2,int hodnota3);  /* Signature: (II)I */
native void vlozHodnotu(double cisDouble,float cisFloat,int cisInt);  /* Signature: (DFI)V */

Teraz si ukážeme ako vyzerá zdrojový kód samotnej zdieľané knižnice vychádzajúci zo zverejneného header súboru.

#include <jni.h>
#include <stdio.h>
#include "primitivni.h"

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisBoolean(JNIEnv *env, jobject obj, jboolean bool){
    printf("Zde je vypsan dany boolean : %d \n",bool);
    jboolean boolea = JNI_TRUE;
    printf("Zde je vypsan dany boolean : %d \n",boolea);
}

JNIEXPORT jboolean JNICALL Java_DatoveTypyPrimitivni_ziskejBoolean(JNIEnv *env, jobject obj){
    jboolean boolea = JNI_FALSE;
    return boolea;
}
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisByte(JNIEnv *env, jobject obj, jbyte bajt){
    printf("Zde je vypsan dany byte : %d \n",bajt);
    jbyte hodnota = 55;
    printf("Zde je vypsan dany byte : %d \n",hodnota);
}

JNIEXPORT jbyte JNICALL Java_DatoveTypyPrimitivni_ziskejByte(JNIEnv *env, jobject obj){
    jbyte hodnota = 22;
    return hodnota;
}
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_vypisZnak(JNIEnv *env, jobject obj, jchar znak){
    printf("Zde je vypsan dany znak : %c \n",znak);
    char zna ='C';
    jchar znakk ='D';
    printf("Zde je vypsan dany znak : %c \n",zna);
    printf("Zde je vypsan dany znak : %c \n",znakk);
}

JNIEXPORT jchar JNICALL Java_DatoveTypyPrimitivni_ziskejZnak(JNIEnv *env, jobject obj){
    char znakC ='X';
    jchar znakJ = znakC;
    return znakJ;
}

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavShort(JNIEnv *env, jobject obj, jshort shortik){
    printf("Zde je vypsan dany Short : %d \n",shortik);
    short cislo = 4561;
    printf("Zde je vypsan dany Short : %d \n",cislo);
}

JNIEXPORT jshort JNICALL Java_DatoveTypyPrimitivni_ziskejShort(JNIEnv *env, jobject obj){
    unsigned short cislo = 56451;
    printf("Zde je vypsan mezi Short : %d \n",cislo);
    jshort ziskejShort = cislo;
    printf("Zde je vypsan mezi Short : %d \n",ziskejShort);
    return ziskejShort;
}

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavInt(JNIEnv *env, jobject obj, jint integer){
    printf("Zde je vypsan dany Integer : %d \n",integer);
}

JNIEXPORT jint JNICALL Java_DatoveTypyPrimitivni_ziskejInt(JNIEnv *env, jobject obj){
    jint hodnota = 45678;
    return hodnota;
}

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavLont(JNIEnv *env, jobject obj, jlong longer){
    printf("Zde je vypsan dany Long : %d \n",longer);
    long hodnota1 = 456123;
    long hodnota2 = 7844456;
    printf("Vypsan vysledek : %d \n",(hodnota1+hodnota2));
}

JNIEXPORT jlong JNICALL Java_DatoveTypyPrimitivni_ziskejLong(JNIEnv *env, jobject obj){
    jlong cisloLong = 456785156;
    return cisloLong;
}

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavFloat(JNIEnv *env, jobject obj, jfloat flot){
    printf("Zde je vypsan dany float : %d \n",flot);
    float cislo1 = 784.657;
    float cislo2 = 46.789;
    printf("Vypsan vysledek : %d \n",(cislo1/cislo2));
}

JNIEXPORT jfloat JNICALL Java_DatoveTypyPrimitivni_ziskejFloat(JNIEnv *env, jobject obj){
    jfloat back = 76546.8876;
    return back;
}

JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavDouble(JNIEnv *env, jobject obj, jdouble doub){
    printf("Zde je vypsan dany double : %d \n",doub);
    double hodno1 = 46657.657;
    double hodno2 = 466333.654;
    printf("Vypsan vysledek : %d \n",(hodno1+hodno2));
}

JNIEXPORT jdouble JNICALL Java_DatoveTypyPrimitivni_ziskejDouble(JNIEnv *env, jobject obj){
    jdouble cisloDouble =45667.358;
    return cisloDouble;
}

Konečne si preberieme vstupné parametre JNI metód:

/* Vychozi nativni metoda v interpretované části */
private native void nastavDouble(double hodnota);
/* Hlavičkový soubor(Header File) - Signature: (D)V */
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavDouble(JNIEnv *, jobject, jdouble)
/* Zdrojový soubor (Source File)*/
JNIEXPORT void JNICALL Java_DatoveTypyPrimitivni_nastavDouble(JNIEnv *env, jobject obj, jdouble doub)
  • JNIEnv * env - Ide o parameter (odkaz) pre rozhranie JNI, ktoré obsahuje metódy ktoré sú nám cez daný parameter sprístupnené
  • jobject obj - trochu problematické, ale najbližšia definícia je, že sa jedná o objekt, ktorý metódu volá. Umožňuje nám pracovať v JNI s objektom, ktorý sa nachádza a bol vytvorený v interpretované časti programu
  • jdouble Doubí - štandardné parametre metódy, tu konkrétne typu double

 

Predchádzajúci článok
JNI - Príklad v Eclipse s C ++
Všetky články v sekcii
JNI - Java Native Interface
Preskočiť článok
(neodporúčame)
JNI - Pole primitívnych dátových typov
Článok pre vás napísal Robert Michalovič
Avatar
Užívateľské hodnotenie:
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
Aktivity