Počítačová hra Tetris slaví 40 let. Alexej Pažitnov dokončil první hratelnou verzi 6. června 1984. Mezitím vznikla celá řada variant. Například Peklo nebo Nebe. Loni měl premiéru film Tetris.
MicroPython (Wikipedie), tj. implementace Pythonu 3 optimalizovaná pro jednočipové počítače, byl vydán ve verzi 1.23.0. V přehledu novinek je vypíchnuta podpora dynamických USB zařízení nebo nové moduly openamp, tls a vfs.
Canonical vydal Ubuntu Core 24. Představení na YouTube. Nová verze Ubuntu Core vychází z Ubuntu 24.04 LTS a podporována bude 12 let. Ubuntu Core je určeno pro IoT (internet věcí) a vestavěné systémy.
Databáze DuckDB (Wikipedie) dospěla po 6 letech do verze 1.0.0.
Intel na veletrhu Computex 2024 představil (YouTube) mimo jiné procesory Lunar Lake a Xeon 6.
Na blogu Raspberry Pi byl představen Raspberry Pi AI Kit určený vlastníkům Raspberry Pi 5, kteří na něm chtějí experimentovat se světem neuronových sítí, umělé inteligence a strojového učení. Jedná se o spolupráci se společností Hailo. Cena AI Kitu je 70 dolarů.
Byla vydána nová verze 14.1 svobodného unixového operačního systému FreeBSD. Podrobný přehled novinek v poznámkách k vydání.
Společnost Kaspersky vydala svůj bezplatný Virus Removal Tool (KVRT) také pro Linux.
Grafický editor dokumentů LyX, založený na TeXu, byl vydán ve verzi 2.4.0 shrnující změny za šest let vývoje. Novinky zahrnují podporu Unicode jako výchozí, export do ePub či DocBook 5 a velké množství vylepšení uživatelského rozhraní a prvků editoru samotného (např. rovnic, tabulek, citací).
Byla vydána (𝕏) nová verze 7.0 LTS open source monitorovacího systému Zabbix (Wikipedie). Přehled novinek v oznámení na webu, v poznámkách k vydání a v aktualizované dokumentaci.
Ačkoliv je výbava Java Class Library s každou verzí lepší a lepší, ne vždy je dostatečná pro některé low level úlohy, nebo Java zkrátka neposkytuje (JITu navzdory) výkon, který nám může poskytnout pečlivě zoptimalizovaný kód. Dalším důvodem, proč JNI vzniklo, je napojení na knihovny systému a další platformně specifické věci – příkladem budiž SWT, které se v závislosti na aktuálním systému skrze JNI knihovny napojuje na nativní knihovny pro tvorbu GUI.
Nevýhodou použití JNI v této situaci je ztráta nezávislosti na hardwarové a softwarové platformě, neboť nativní knihovna musí být zkompilována například pro x86 a amd64 zvlášť a jednu knihovnu nemůžeme použít pro Windows a Linux zároveň. Je tedy důležité k JNI přistupovat s rozmyslem.
Opačný přístup je nasazování Javy v nativních aplikacích, což bude tématem pozdějších článků z tohoto seriálu. V této situaci nepředstavuje použití Javy žádné speciální komplikace, snad jen to, že samozřejmě musíme zajistit, aby na cílovém systému bylo k dispozici funkční a dostatečně aktuální JRE. Možná se ptáte, nač kazit rychlou nativní aplikaci tou „pomalou a rozežranou“ Javou. Java díky své mocnosti a dostupnosti nepřeberného množství knihoven představuje jednoho z kandidátů na tvorbu rozšíření do nativních aplikací. Snad nejznámější aplikací, kde se Java takto používá, je OpenOffice.org; nutno však podotknout, že za pomalostí tohoto kancelářského balíku není Java. Ba naopak, Java se dle mých zkušeností dokáže chovat přinejmenším stejně paměťově skromně jako jiné jazyky typické pro tento účel (Python a spol.).
Oproti (mnohdy interpretovaným) skriptovacím jazykům, které typicky obsazují místo jazyků pro rozšíření, Java nabízí vlastnosti silně typovaného jazyka, vyšší výkon díky JIT kompilaci a kromě toho garanci „stabilního zázemí“, kdy celá Java Class Library je zaručenou součástí každé instalace JRE. Uživatel si tak nemusí instalovat spousty wrapperů pro zvolený skriptovací jazyk a programátor nemusí řešit, co dělat, když knihovna nebude nainstalovaná, ačkoliv uznávám, že nenávist k desítkám instalovaných py a -ruby wrapperů je spíše mým osobním pohledem a záští.
JNI bohužel patří mezi API, která jsou Sunem a nyní Oraclem dosti zanedbávána. Na rozdíl od samotné Javy je dokumentace JNI dosti strohá (dva HTML soubory) a některé věci je nutné zjišťovat metodou pokus-omyl. Za poslední roky tato dokumentace dostala pouze "facelift", ale že nefunguje ani skákání na jednotlivé odstavce v dokumentu, to už nikoho nezajímalo. Bohužel i z hlediska používání rozhraní je třeba vždy myslet na to, že JNI si nikdy neporadí se špatným argumentem. Null pointer znamená pád, šáhnutí za konec pole znamená pád (žádné ArrayOutOfBoundsException) a překlep v názvu nativní metody při registraci znamená také pád, a to dokonce ještě s pěkným ohňostrojem.
Ne nadarmo se při psaní nativních knihoven doporučuje v knihovnách provádět holé minimum práce a zbytek napsat v Javě. Tímto pravidlem se řídí i samotný Sun/Oracle. Kromě nižšího rizika chyb je tu i zjevný důvod, že údržba takového kódu je ve výsledku snazší. Je to dobré pro přehlednost, neboť veškerá logika je pak na jediném místě a ne rozdělena mezi Java a C kód.
Nejprve se podíváme na to, jak proces načítání a používání nativních knihoven funguje na straně Javy. Nativní metody se v Javě vyznačují klíčovým slovem native
, taková jednoduchá třída tedy může vypadat následovně:
package test; public class TestNative { public static void javaMethod() { /* ... */ } public static native int nativeMethod(int myNumber); }
Pokud zavoláme metodu nativeMethod() v této situaci (kdy jsme nedodali odpovídající nativní kód), volání selže s výjimkou java.lang.UnsatisfiedLinkError: test.test.TestNative.nativeMethod(I)I
. Dalším krokem je nechat si vygenerovat hlavičkový soubor s deklaracemi pro jazyk C – k romu slouží konzolový nástroj javah
, jenž je součástí JDK. Javah pracuje nad zkompilovanými třídami, volitelně mu tedy předáváme classpath s umístěním těchto tříd.
$ javah -classpath ./build/classes test.TestNative $ ls *.h test_TestNative.h
V aktuálním adresáři nám vznikne hlavičkový soubor pojmenovaný podle balíčku a třídy. Soubor je přizpůsoben pro použití v C i C++.
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class test_TestNative */ #ifndef _Included_test_TestNative #define _Included_test_TestNative #ifdef __cplusplus extern "C" { #endif /* * Class: test_TestNative * Method: nativeMethod * Signature: (I)I */ JNIEXPORT jint JNICALL Java_test_TestNative_nativeMethod (JNIEnv *, jclass, jint); #ifdef __cplusplus } #endif #endif
Naše oči hned zabrousí k funkci void Java_test_TestNative_nativeMethod(JNIEnv *, jclass, jint)
, kterou máme naimplementovat. Uděláme si takový malý Hello world. Soubor test_TestNative.cpp:
#include "test_TestNative.h" #include <iostream> jint Java_test_TestNative_nativeMethod(JNIEnv* env, jclass myClass, jint myNumber) { std::cout << "Hello world!\n"; std::cout << "Argument value: " << myNumber << std::endl; return -myNumber; }
Nyní si z tohoto zdrojáku zkompilujeme sdílenou knihovnu. Samozřejmě by bylo lepší použít nějaký Makefile nebo rovnou použít autotools a podobné, ale pro jednoduchost ukážu příkaz přímo pro GCC s include cestami dle mého systému:
$ g++ -fPIC -shared \ > -I /usr/lib/jvm/java-6-sun-1.6.0.21/include \ > -I /usr/lib/jvm/java-6-sun-1.6.0.21/include/linux \ > -o /tmp/libtestnative.so test_TestNative.cpp
Teď naší javovskou třídu obohatíme o metodu main a necháme Javu načíst naší nativní knihovnu:
public static void main(String[] args) { System.loadLibrary("testnative"); int r = nativeMethod(123); System.out.println("The native method has returned " + r); }
Javovské System.loadLibrary respektuje zvyklosti z různých operačních systémů, na Linuxu je to prefix lib před názvem knihovny. System.loadLibrary("testnative")
tedy na Linuxu zkusí načíst libtestnative.so
. Poslední věc je Javě říci, kde má knihovnu hledat, a to nastavením java.library.path
(něco na způsob známého LD_LIBRARY_PATH
). Nyní tedy nazdar světe!
$ java -Djava.library.path=/tmp -cp build/classes test.TestNative Hello world! Argument value: 123 The native method has returned -123
Z ukázky tedy vidíme, že předávání a vracení primitivních typů je velmi jednoduché. Kromě argumentů, které předáváme z Javy, dostává naše nativní funkce ještě dva argumenty. Ten první – JNIEnv* env
– představuje bránu do javovského světa a je objektem, který budeme brzy velmi aktivně využívat. Jinak než pomocí JNIEnv nelze funkce JNI volat, snad jen s výjimkou funkce pro vytvoření JVM z nativní aplikace.
Druhý argument – jclass myClass
– dostávají pouze statické metody a jde o céčkovou reprezentaci instance java.lang.Class
, jež bychom v javovském kódu našli jako test.TestNative.class
.
V příštím díle se přesuneme od primitivních typů k objektům a zkusíme si vytvořit nějaký ten String
.
Nástroje: Tisk bez diskuse
Tiskni Sdílej:
třeba s nemazáním lokálních referencí v cyklu (padačka)To padalo kvůli překročení maximálního počtu referencí ve scope? Jinak si teď nedovedu představit, proč by to padalo.
Z tohto dovodu je dobre pouzivat zasadu, ze co najviac sa vyhybat nativnym knizniciam a ked ich uz musim pouzit tak izolovat izolovat a zasa izolovat a to najlepsie do separatneho procesu.Což má ale dopad na výkon, v některých případech může být i dost vysoký...
Pri desktopovych aplikaciach to este nemusi byt velky problem, ale ked vam padne cely server, tak to potom zacina zabava.Máš pravdu, ale je to trochu přehnané - takhle to mají všechny nativní aplikace a myslím si, že obecně jsou tyto na serverech v průměru v převaze
Podla mna drtiva vacsina web aplikacii su vytvarane v php,java,.net a python a to vacsinou bez pouzitia nativnych kniznic.Nevěděl jsem, že se bavíme o webových aplikacích...