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 | - |
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: DatoveTypyPrimitivni - 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: DatoveTypyPrimitivni - 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 |
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