abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
16.8. 19:00 | Nová verze

Byla vydána verze 18.08.0 KDE Aplikací (KDE Applications). Přehled novinek v kompletním seznamu změn a na stránce s dalšími informacemi.

Ladislav Hagara | Komentářů: 0
16.8. 18:44 | Pozvánky

Spolek OpenAlt zve příznivce otevřených řešení a přístupu na 155. brněnský sraz, který proběhne v pátek 17. srpna od 18:00 na zahrádce restaurace Tanganika (Horova 35). V případě nepřízně počasí uvnitř. Tentokrát bude sraz pojat tématicky. Vzhledem k blížícímu se 50. výročí invaze vojsk Varšavské smlouvy do Československa proběhne malá výstava. Kromě literatury budou k vidění též originály novin z 21. srpna 1968, dosud nikde nezveřejněné fotky okupovaného Brna a původní letáky rozdávané v ulicích.

Ladislav Hagara | Komentářů: 0
16.8. 01:00 | Komunita

Měsíc po Slackware slaví 25 let také Debian. Přesně před pětadvaceti lety, 16. srpna 1993, oznámil Ian Murdock vydání "Debian Linux Release".

Ladislav Hagara | Komentářů: 10
15.8. 06:00 | Nová verze

Byla vydána nová verze 1.26 editoru zdrojových kódů Visual Studio Code (Wikipedie). Přehled novinek i s náhledy a animovanými gify v poznámkách k vydání. Představení novinek také na YouTube.

Ladislav Hagara | Komentářů: 27
15.8. 03:00 | Nová verze

Po více než 3 měsících vývoje od vydání verze 2.12.0 byla vydána nová verze 3.0.0 otevřeného emulátoru procesorů a virtualizačního nástroje QEMU (Wikipedie). Přispělo 169 vývojářů. Provedeno bylo více než 2 300 commitů. Přehled úprav a nových vlastností v seznamu změn. Proč verze 3.0.0 a ne 2.13.0? Není to kvůli triskaidekafobii. QEMU letos v březnu slavilo 15 let od oznámení verze 0.1 a to je dle vývojářů dobrý důvod pro novou major verzi. Vývojáři mají v plánu zvyšovat major verzi jednou ročně, vždy s prvním vydáním v daném roce.

Ladislav Hagara | Komentářů: 3
14.8. 22:11 | Bezpečnostní upozornění

Intel potvrdil (INTEL-SA-00161) další bezpečnostní problém ve svých procesorech. Problém byl pojmenován L1 Terminal Fault aneb L1TF. Popis problému přímo od Intelu na YouTube. Jedná se o CVE-2018-3615 (SGX), CVE-2018-3620 (OS/SMM) a CVE-2018-3646 (VMM). Další informace na stránce Foreshadow nebo přímo v dnešním commitu do Linuxu.

Ladislav Hagara | Komentářů: 19
14.8. 12:33 | IT novinky

Po více než 4 letech bylo vydáno RFC 8446 popisující verzi 1.3 protokolu TLS (Transport Layer Security). Popis novinek i historie TLS například v příspěvku na blogu Cloudflare.

Ladislav Hagara | Komentářů: 0
14.8. 11:11 | Zajímavý software

V roce 1998 uvedla společnost Tiger Electronics na trh elektronickou hračku, malého chlupatého tvora s velkýma ušima, Furby. Furby patřil k nejžádanějším hračkám. Během tří let se jich prodalo více než 40 milionů. Furby již tenkrát reagoval na světlo, zvuk, polohu, doteky a přítomnost dalších Furby. Sám mluvil a pohyboval se. Firmware uvnitř simuloval postupný vývoj a učení. Zdrojový kód tohoto firmwaru byl zveřejněn na Internet Archive [Hacker News].

Ladislav Hagara | Komentářů: 21
14.8. 02:00 | Nová verze

Australská společnost Blackmagic Design oznámila vydání verze 15 svého proprietárního softwaru pro editování videa a korekci barev DaVinci Resolve běžícího také na Linuxu. Představení nových vlastností na YouTube. Základní verze DaVinci Resolve je k dispozici zdarma. Plnou verzi DaVinci Resolve Studio lze koupit za 299 dolarů. Před rokem to bylo 995 dolarů.

Ladislav Hagara | Komentářů: 0
13.8. 21:00 | Zajímavý projekt

Cílem projektu DXVK bylo vytvořit vrstvu kompatibility mezi Direct3D 11 a Vulkanem a začlenění této vrstvy do Wine. Direct3D 10 nad Vulkanem bylo možné řešit mezikrokem pomocí vrstvy DXUP překládající Direct3D 10 na Direct3D 11. Vývojáři DXVK se rozhodli přímo podporovat Direct3D 10. Podpora byla začleněna do hlavní větve na GitHubu.

Ladislav Hagara | Komentářů: 4
Používáte zařízení („chromebook“, „chromebox“ či tablet) s ChromeOS?
 (6%)
 (3%)
 (13%)
 (77%)
Celkem 202 hlasů
 Komentářů: 9, poslední 14.8. 21:03
    Rozcestník

    Java Native Interface: propojujeme Javu a C/C++ – 4

    22. 12. 2010 | Luboš Doležel | Programování | 2685×

    Doposud jsme si hráli jen s objekty, které nám předalo JNI. Je na čase nabýt samostatnosti a začít s třídami a instancemi pracovat samostatně. Také začneme řešit javovské výjimky.

    Obsah

    Načítáme třídy

    link

    Základem je funkce FindClass, která nám vrátí objekt jclass představující načtenou třídu. Pokud považujeme jclass za ekvivalent java.lang.Class, pak funkce FindClass odpovídá metodě Class.forName(). Volání je vcelku jednoduché:

    jclass jlInteger = env->FindClass("java/lang/Integer");
    

    Nejprve si řekneme, že jlInteger v naší ukázce je lokální reference, takže podle toho s ní musíme zacházet. Druhá věc je podoba, v jaké předáváme jméno třídy. V případě FindClass jméno třídy odpovídá v podstatě jménu souboru bez přípony .class. Mělo by stačit si pamatovat základní pravidla: místo teček jsou lomítka (podadresáře ve struktuře balíčků) a podtřídy se oddělují znakem $. Máme li například třídu Pokus v balíčku cz.abclinuxu a ta má v sobě enum Nesmysly, označení Nesmysly je cz/abclinuxu/Pokus$Nesmysly. První anonymní třída v druhé anonymní třídě ve třídě pokus by pak byla cz/abclinuxu/Pokus$2$1. Pokud tvoříte něco složitějšího a váháte, je nejsnazší se prostě podívat na jméno souboru.

    A teď, co s tím? Než se vrhneme na vytváření instancí, podíváme se na dodatečné metody pro práci s třídami. První věc je obdoba javovského operátoru instanceof:

    extern jstring myString; // Někde máme schovaný řetězec...
    
    jclass jlString = env->FindClass("java/lang/String");
    assert(env->IsInstanceOf(myString, jlString) == JNI_TRUE);
    

    Další věc je obdoba metody Class.isAssignableFrom(): IsAssignableFrom. Praktický rozdíl oproti IsInstanceOf spočívá v tom, že IsAssignableFrom pracuje nad dvěma třídami a nepotřebuje instanci.

    jclass jlObject = env->FindClass("java/lang/Object");
    jclass jlString = env->FindClass("java/lang/String");
    
    assert(env->IsAssignableFrom(jlString, jlObject) == JNI_TRUE);
    

    Pak ještě máme tyto funkce:

    • GetSuperclass – k předané třídě vrátí rodiče této třídy; pokud rodič neexistuje (například u java.lang.Object), vrátí NULL.
    • DefineClass – obdoba ClassLoader.defineClass(): načte předaný bajtkód jako novou třídu. To už je taková "vyšší dívčí".

    Vytváříme instance

    link

    K čistému vytvoření instance slouží funkce AllocObject – té dáme jclass a z druhé strany vyleze jobject. Obráceně funguje GetObjectClass, které si vezme jobject a vrátí odpovídající jclass (obdoba Object.getClass()). Dá se očekávat, že při vytváření objektu většinou chceme hned zavolat nějaký ten konstruktor. Od toho slouží trojice funkcí NewObject, NewObjectA a NewObjectV – ty vytvoří objekt a o zavolání konstruktoru se postarají.

    Signatury metod

    link

    Ale než začneme volat konstruktory, je tu ještě jedna funkce, kterou musíme znát: GetMethodID. GetMethodID budeme používat, ať už chceme volat konstruktor nebo obyčejnou metodu. GetMethodID přebírá jclass, název metody (v případě konstruktoru používáme <init>) a její signaturu. Vrací pak jMethodID (nebo NULL a výjimku navrch), které potřebujeme, kdykoliv k nějakému volání metody dochází.

    jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);

    Název metody name je docela jasná věc, se signaturou už je to horší. Takže se ještě naučíme tvořit signatury – taková signatura vypadá následovně: (argumenty)návratový_typ. Návratovým typem konstruktorů je void. K vytváření signatur využijeme tabulku, jež jsem ukázal ve druhém díle tohoto seriálu (tabulka primitivních datových typů, sloupeček identifikátor), kterou si pomyslně rozšíříme o tyto dvě speciality:

    • Identifikátor návratového typu void je V
    • Identifikátor instance objektu je Lidentifikátor_třídy;, přičemž identifikátorem třídy se myslí to samé, co jsme na začátku tohoto článku předávali funkci FindClass. Příklad pro java.lang.String: Ljava/lang/String;. Nezapomínejte na středník!

    Argumenty dáváme přímo za sebou, metoda void metoda(int i1, String s2, float f3) tedy bude mít signaturu (ILjava/lang/String;F)V. Následujícím způsobem tedy najdeme konstruktor Integer(String s) (třída java.lang.Integer):

    jclass jlInteger = env->FindClass("java/lang/Integer");
    jmethodID konstruktor = env->GetMethodID(jlInteger, "<init>", "(Ljava/lang/String;)V");
    

    Voláme konstruktor

    link

    Konečně už máme vše potřebné pro vytvoření objektu. Jaký je ale rozdíl mezi NewObject, NewObjectA a NewObjectV?

    • jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)

      Funkce s variabilním počtem argumentů. Hned po ID metody tedy začneme předávat argumenty.

    • jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)

      Přebírá argumenty jako odkaz na začátek pole objektů jvalue. jvalue je ve skutečnosti céčkový union, takže jeho použití vypadá následovně:

      jvalue args[3];
      
      args[0].i = 5;
      args[1].l = myString;
      args[2].f = 3.0f;
      
      // a můžeme předat args
      

      Využijeme při tvorbě různých wrapperů.

    • jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)

      Funkce, která přebírá seznam variabilních argumentů :-) Pokud děláme nějaký jednoduchý wrapper kolem NewObject a naše funkce taktéž přebírá variabilní počet argumentů, bezpracně jej můžeme poslat dál v podobě va_list. Používání va_list už je mimo rozsah tohoto článku. Vztah mezi NewObjectV a NewObject je jako mezi vprintf a printf.

    Takže konečně vytvořme objekt:

    extern jstring myString;
    
    jclass jlInteger = env->FindClass("java/lang/Integer");
    jmethodID konstruktor = env->GetMethodID(jlInteger, "<init>", "(Ljava/lang/String;)V");
    jobject ii = env->NewObject(jlInteger, konstruktor, myString);
    

    A máme na světě svůj první vlastnoruční objekt, respektive lokální referenci na něj! Náš kód je obdobou tohoto javovského kódu:

    Integer ii = new Integer(myString);
    

    Na volání ostatních metod se podíváme příště, tentokrát nám ještě zbývá čas na výjimky.

    Výjimky

    link

    Seznam možných výjímek po volání JNI najdete v dokumentaci. Výjimky pak ještě může házet volání libovolné javovské metody. Protože je JNI céčkové API a C výjimky nemá, musíme výjimky ošetřovat ručně. Prvním krokem je vědět, jestli k výjimce došlo. Jednoduchá funkce ExceptionCheck nám v tom udělá jasno.

    
    jclass jlInteger = env->FindClass("java/lang/Integer");
    if (env->ExceptionCheck() == JNI_TRUE)
    {
    	cerr << "Pohroma!!!\n";
    	// ...?
    }
    

    Často ale chceme s výjimkou rovnou pracovat. V takovém případě můžeme ExceptionCheck rovnou přeskočit a přikročit k ExceptionOccurred, které nám vrátí nějakého potomka java.lang.Throwable. Nesmíme ale zapomínat JNI říci, že jsme se o výjimku postarali. Tentokrát jsme už chytřejší než v předchozí ukázce a zavoláme ExceptionClear. Před vymazáním pamatáky po výjimce ještě ale použijeme (ladící) funkci ExceptionDescribe, která na stderr vypíše popis výjimky a její zásobník volání. Ušetří nám to volání oblíbeného printStackTrace().

    jclass jlInteger = env->FindClass("java/lang/Integer");
    if (jthrowable ex = env->ExceptionOccurred())
    {
    	cerr << "Pohroma:\n";
    	env->ExceptionDescribe();
    	env->ExceptionClear();
    }
    

    Dobrá rada: jakmile máte daný jthrowable "v ruce", okamžitě (respektive hned po ExceptionDescribe, pokud jej používáte) volejte ExceptionClear. Může se stát, že v obsluze výjimky budete např. najednou chtít zavolat nějakou javovskou metodu, dáte takový kód před ExceptionClear a pak se budete divit, jaktože se to chová divně a kolabuje to. Pokud máte v JNI výjimku, musíte ji nejprve odstranit, než budete dělat něco dalšího!

    Házíme výjimky

    link

    Poslední věcí dnešního článku je výjimky nejen chytat, ale i házet. Na to existují dvě funkce: Throw a ThrowNew. První si od nás vezme libovolný jthrowable a po ukončení naší nativní funkce poletí javovským kódem výjimka. Druhá funkce usnadňuje házení výjimek tím, že výjimku pro nás ještě vytvoří. Předpokladem pro užití ThrowNew je to, že třída výjimky, kterou chceme hodit, má konstruktor, který má jediný argument řetězec s popisem chyby. V ostatních případech musíme konstrukci výjimky provádět sami. Příklad se ThrowNew:

    jclass jlException = env->FindClass("java/lang/Exception");
    env->ThrowNew(jlException, "Stala se strašlivá chyba!");
    

    Popis chyby předáváme jako řetězec v UTF-8. Tento kód je obdobou javovského throw new Exception("Stala se strašlivá chyba!");.

    Co bude příště

    link

    Příště začneme volat metody a pokud zbyde čas, tak se podíváme i na přístup ke členským proměnným.

           

    Hodnocení: 100 %

            špatnédobré        

    Nástroje: Tisk bez diskuse

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    22.12.2010 06:19 petr_p | skóre: 59 | blog: pb
    Rozbalit Rozbalit vše Re: Java Native Interface: propojujeme Javu a C/C++ – 4

    V řetězci signatury konstruktoru chybí první a třetí argument:

    jmethodID konstruktor = env->GetMethodID(jlClass, "<init>", "(Ljava/lang/String;)V");
    jobject ii = env->NewObject(jlInteger, konstruktor, 5, myString, 3.0f);
    Luboš Doležel (Doli) avatar 22.12.2010 11:04 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
    Rozbalit Rozbalit vše Re: Java Native Interface: propojujeme Javu a C/C++ – 4
    Díky za upozornění, tohle místo jsem přepisoval a přepsal jsem ho blbě. Původně mělo jít o new Integer(myString). Opravím to.
    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.