Programovanie

Zlúčenie Java a Win32: Nový spôsob vývoja aplikácií pre Windows

Spravodajské médiá zamerali pozornosť v posledných týždňoch na niekoľko fúzií. Banky, automobilové korporácie a obchodné reťazce oznámili, že sa spájajú. Viete si predstaviť šok, ak by sa spoločnosti Sun Microsystems a Microsoft niekedy rozhodli zlúčiť? No nemyslím si, že by sme mali zadržiavať dych. Myslím si však, že spoločnosti Sun a Microsoft by sa mohli navzájom niečo naučiť. Koniec koncov, obe spoločnosti vyvinuli dobré produkty - konkrétne Java a Win32. Podľa môjho názoru je krivka učenia Java oveľa kratšia ako krivka učenia C ++. Win32 je zároveň jedným z dôležitých dôvodov, prečo má Microsoft Windows 95 / NT spustený na niekoľkých miliónoch počítačov. Zdá sa byť prirodzené zlúčiť Java a Win32, aby poskytli vývojárom výhodu, ktorú potrebujú na vytváranie lepších aplikácií pre Windows v kratšom čase. To je zameranie tohto článku.

Na začiatku...

Prvé aplikácie pre Windows boli napísané v jazyku C. Zatiaľ čo C bola v poriadku pre malé aplikácie, pre vývojárov bolo ťažké používať tento jazyk na organizáciu väčších aplikácií. Problém sa sústredil na model zasielania správ Windows a na skutočnosť, že C je skôr štruktúrovaný ako objektovo orientovaný jazyk. Tradičné aplikácie používajúce C by vytvorili hlavné okno a priradili by im funkciu spätného volania (známu ako postup okna) do tohto okna. Kedykoľvek sa v tomto okne stalo čokoľvek, Windows by spustil správu do okna volaním procedúry okna. Procedúra okna by reagovala tak, že by sa správa najskôr identifikovala pomocou veľkého príkazu na prepínanie medzi prípadmi a potom sa správa spracovala. Ako to často býva, stav by bolo treba ukladať pomocou lokálnych statických premenných alebo globálnych premenných. Výsledkom veľkej aplikácie môže byť veľa takýchto premenných. Táto paradigma fungovala dobre pre menšie aplikácie, ale ukázala sa ako škodlivá pre väčšie aplikácie. Bolo treba niečo urobiť.

Jazyk C sa vyvinul zo štruktúrovaného jazyka do objektovo orientovaného jazyka - jazyka s názvom C ++. Príjemné na objektovo orientovanom jazyku je, že dáva vývojárom možnosť modelovať entity v reálnom svete prirodzenejším spôsobom pomocou objektov.

Pred niekoľkými rokmi Microsoft uviedol nástroj pre vývojárov, ktorí chceli vytvárať aplikácie pre Windows pomocou C ++. Tento produkt sa stal známym ako Visual C ++. Jednou z funkcií zavedených vo Visual C ++ bol aplikačný rámec známy ako Microsoft Foundation Classes (MFC). Rámec MFC je kolekcia tried C ++, napísaná a testovaná vývojármi spoločnosti Microsoft, ktorá implementuje množstvo základných funkcií systému Windows. Veľa softvérových konceptov - od panelov nástrojov a stavových riadkov po model zobrazenia dokumentu založený na architektúre Model-View-Controller - je implementovaných v MFC. Myšlienkou MFC je ušetriť čas počas vývoja pomocou kódu MFC pre väčšinu aplikácií a následným rozšírením MFC tak, aby poskytoval jedinečné schopnosti tejto aplikácie - prostredníctvom základných objektovo orientovaných konceptov zapuzdrenia, dedenia a polymorfizmu.

Vývoj softvéru s MFC však nie je ľahká úloha. Aby vývojári mohli písať dnešné aplikácie pre Windows pomocou C ++ a MFC, musia dobre rozumieť koncepciám objektovo orientovaného programovania, syntaxe a zvláštnostiam C ++, API systému Windows a MFC.

V ideálnom prípade potrebujú vývojári jediný jazyk a platformu, ktorá im umožní písať aplikácie iba raz a potom ich všade nasadiť. V snahe uspokojiť túto potrebu spoločnosť Sun implementovala platformovo neutrálne verzie mnohých rozhraní API systému Windows okrem rozhraní API jedinečných pre jazyk Java (napríklad Java Card). Rozhrania API zaoberajúce sa správou súborov, poštou, pomocou, multimédiami a bezpečnosťou majú vo svete Windows obdoby. Z toho vyplýva jedna veľká výhoda pre vývojárov Windows: Namiesto toho, aby sa vývojári naučili veľa Windows API spolu s C ++ a MFC, môžu sa sústrediť na učenie Javy a jej API. Potom môžu pomocou Java vyvíjať aplikácie pre Windows. Tu je postup.

Invocation API

Dizajnéri Javy prišli s mechanizmom, ako dostať kód Java tak, aby hovoril s kódom C ++. Tento mechanizmus využíva kolekciu C ++ API známych ako Java Native Interface (JNI). Niekoľko z týchto rozhraní API sa spojilo a sú spoločne známe ako Invocation API.

Invocation API sa skladá z niekoľkých funkcií JNI, ktoré umožňujú vývojárovi vložiť virtuálny stroj Java (JVM) do ľubovoľnej natívnej aplikácie. S integrovaným JVM má natívna aplikácia prístup k celému JVM uskutočňovaním hovorov JNI.

JVM sa vytvára volaním do JNI_CreateJavaVM () funkcia. Táto funkcia presunie ukazovateľ na a JDK1_1InitArgs štruktúra ako argument. Táto štruktúra poskytuje predvolené nastavenia pre JVM. Predvolené hodnoty možno prepísať.

Na získanie predvoleného nastavenia je potrebné použiť inú funkciu JNI, JNI_GetDefaultJavaVMInitArgs (), treba zavolať. Táto funkcia smeruje na JDK1_1InitArgs štruktúra ako argument. Typická postupnosť volaní sa nachádza v nasledujúcom zozname:

JDK1_1InitArgs vm_args; vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); 

Pred zavolaním je potrebné nastaviť pole verzie JNI_GetDefaultJavaVMInitArgs (). Toto pole zaisťuje, že aplikácia používa správny JVM. Hodnota 0x00010001 kóduje hlavné číslo verzie požadovaného JVM vo vysokých 16 bitoch a vedľajšie číslo verzie vo vysokých 16 bitoch. Hodnota 0x00010001 znamená, že do aplikácie bude vložený akýkoľvek JVM, ktorého číslo verzie je 1.1.2 alebo vyššie.

Niekoľko zaujímavých oblastí obsahuje JDK1_1InitArgs štruktúru, ale jediné pole, ktoré v tomto článku spomenieme, je pole známe ako triedna cesta. Toto pole je dôležité, pretože informuje JVM, kde sa nachádzajú súbory classes.zip a súbory tried aplikácií.

Raz JDK1_1InitArgs štruktúra bola inicializovaná, JVM je možné vytvoriť volaním na JNI_CreateJavaVM (), ako je uvedené v nasledujúcom zozname:

JavaVM * jvm; JNIEnv * env; rc = JNI_CreateJavaVM (& jvm, & env, & vm_args); 

V tomto okamihu funguje JNI FindClass () a CallStaticVoidMethod () by bol zavolaný na nájdenie vhodnej počiatočnej triedy Java a počiatočnej hlavnej metódy.

Keď už JVM nie je potrebný, je zničený volaním na DestroyJavaVM (), ako v nasledujúcom zozname.

jvm-> DestroyJavaVM () 

Ako nám teda rozhranie Invocation API umožňuje vytvárať aplikácie Win32 pomocou Javy? Nasledujúci príklad poskytuje odpoveď.

Príklad

Rozhodol som sa vytvoriť konzolovú aplikáciu Win32 podobnú PKZIP, ale moja aplikácia by bola o niečo jednoduchšia. Poskytovalo by to iba možnosť vypísať všetky súbory v archíve zip a extrahovať súbory. Moja aplikácia by sa spustila z príkazového riadku pomocou nasledujúcej syntaxe:

c: \> zip [súbor -x] zip 

čím -X je vlajka extrakcie, spis je názov súboru, ktorý sa má extrahovať, a PSČ je názov archívu s príponou zip alebo bez nej.

Nasledujúci zoznam zobrazuje zdrojový kód C ++ zip.cpp. Tento kód implementuje spustiteľný ovládač ZIP. Tento ovládač načíta JVM, analyzuje argumenty príkazového riadku, vyhľadá PSČ súbor triedy, vyhľadá hlavnú metódu v rámci súboru PSČ súbor triedy, spustí hlavnú metódu (odovzdanie zoznamu argumentov tejto metóde) a uvoľní JVM.

// ================================================= === // zip.cpp // // ZIP spustiteľný ovládač // // podporuje Java Virtual Machine (JVM) 1.1.2 alebo vyšší // ================== ===================================include #include #include #include #define BUFSIZE 80 // == =============================================== // Handler / / // Ovládač ovládania konzoly // // Ignoruje všetky pokusy o vypnutie aplikácie. // // Argumenty: // // dwCtrlType - typ riadiacej udalosti // // Return: // // TRUE (ignorovať udalosť) // =================== ============================== BOOL Handler (DWORD dwCtrlType) {návrat PRAVDA; } // ======================================= // // // // Zip Vstupný bod spustiteľného ovládača // // Argumenty: // // argc - počet argumentov príkazového riadku // argv - pole argumentov príkazového riadku // // Return: // // 0 (úspech) alebo 1 (zlyhanie) / / ======================================= int main (int argc, char * argv [ ]) {int i; jint ret; JNIEnv * env; JavaVM * jvm; jclass clazz; jmethodID mid; JDK1_1InitArgs vm_args; char szBuffer [BUFSIZE], szClassPath [BUFSIZE * 2 + 15]; // Zabráňte vypnutiu aplikácie v dôsledku stlačenia klávesov Ctrl-Break alebo Ctrl-C, // kliknutia na tlačidlá na zatvorenie okna, odhlásenia používateľa alebo vypnutia systému. SetConsoleCtrlHandler ((PHANDLER_ROUTINE) Handler, TRUE); // Získajte predvolené inicializačné argumenty pre JVM verzie 1.1.2 alebo novšej. vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); // Povedzte JVM, kde nájdete súbory aplikačných tried a classes.zip. GetPrivateProfileString ("CONFIG", "PATH", ".", SzBuffer, 80, "zip.ini"); wsprintf (szClassPath, "% s;% s \ classes.zip;", szBuffer, szBuffer); vm_args.classpath = szClassPath; // Pokus o vytvorenie inštancie JVM. if ((ret = JNI_CreateJavaVM (& jvm, & env, & vm_args)) NewStringUTF (""); jobjectArray str_array = env-> NewObjectArray (argc - 1, env-> FindClass ("java / lang / String"), jstr); pre (i = 1; i NewStringUTF (argv [i])) == 0) {fprintf (stderr, "nedostatok pamäte \ n"); návrat 1; } env-> SetObjectArrayElement (str_array, i - 1, jstr); } // Pokus o nájdenie triedy zip. if ((clazz = env-> FindClass ("zip")) == 0) {fprintf (stderr, "Nemôžem nájsť triedu zip. Exiting ... \ n"); návrat 1; } // Pokus o nájdenie hlavnej metódy triedy zip. if ((mid = env-> GetStaticMethodID (clazz, "main", "([Ljava / lang / String;) V")) == 0) {fprintf (stderr, "Nemôžem nájsť hlavnú metódu. Končí sa. .. \ n "); návrat 1; } // Spustiť hlavnú metódu. env-> CallStaticVoidMethod (clazz, mid, str_array); // Zničte inštanciu JVM. jvm-> DestroyJavaVM (); návrat 0; } 

Všimnite si volanie Win32 GetPrivateProfileString () funkcia. Táto funkcia vyhľadá súbor s názvom zip.ini (ktorý by sa nachádzal v adresári Windows - zvyčajne c: \ windows pod Windows 95 alebo c: \ winnt pod Windows NT). Účelom tohto súboru je držať cestu, kde je nainštalovaná aplikácia ZIP. JVM bude v tomto umiestnení hľadať súbory classes.zip a triedy aplikácií (bez ohľadu na to, odkiaľ sa volá aplikácia ZIP).

Ďalšou položkou, ktorú je potrebné poznamenať, je volanie na číslo SetConsoleCtrlHandler () Win32 API. Toto API zabraňuje klávesovým skratkám Ctrl-C alebo Ctrl-Break - okrem iných udalostí - zastaviť aplikáciu pred jej dokončením. To môže, ale nemusí byť žiaduce, v závislosti od aplikácie.

Aplikácia ZIP je napísaná v jazyku Java. Poskytuje používateľom možnosť prezerať obsah archívnych súborov zip a tiež schopnosť extrahovať jednotlivé súbory z týchto archívov. Nasledujúci zoznam obsahuje zdrojový kód do formátu ZIP.

$config[zx-auto] not found$config[zx-overlay] not found