Spajanje Jave i Win32: Novi način za razvoj Windows aplikacija

Novinski su mediji posljednjih tjedana usmjerili pozornost na niz spajanja. Banke, automobilske korporacije i trgovački lanci najavili su da se spajaju. Možete li zamisliti šok ako se Sun Microsystems i Microsoft ikad odluče spojiti? Pa, mislim da ne bismo trebali zadržavati dah. Međutim, mislim da bi Sun i Microsoft mogli nešto naučiti jedni od drugih. Napokon, obje su tvrtke razvile dobre proizvode - naime Java i Win32. Po mom mišljenju, krivulja učenja Java mnogo je kraća od krivulje učenja C ++. Istodobno, Win32 je jedan od važnih razloga zašto Microsoft ima Windows 95 / NT pokrenut na nekih oko milijun računala. Čini se prirodnim spojiti Javu i Win32 kako bi se programerima pružilo prednost koja im je potrebna za stvaranje boljih Windows aplikacija u kraćem vremenskom roku. To je fokus ovog članka.

U početku...

Prve Windows aplikacije napisane su na jeziku C. Iako je C bio u redu za male programe, programerima je bilo teško koristiti ovaj jezik za organizaciju većih aplikacija. Problem se usredotočio na Windowsov model razmjene poruka i činjenicu da je C strukturirani, a ne objektno orijentirani jezik. Tradicionalne aplikacije koje koriste C stvorile bi glavni prozor i dodijelile funkciju povratnog poziva (poznata kao postupak prozora) do ovog prozora. Kad god bi se s ovim prozorom dogodilo nešto posljedica, Windows bi ispalio poruku u prozor pozivajući postupak prozora. Prozorni postupak reagirao bi prvo identificirajući poruku putem ogromne naredbe prekidača, a zatim obrađivao poruku. Kao što je često slučaj, stanje bi trebalo biti spremljeno putem lokalnih statičkih varijabli ili globalnih varijabli. Velika aplikacija mogla bi rezultirati mnogim takvim varijablama. Ova je paradigma dobro funkcionirala za manje programe, ali pokazala se štetnom za veće programe. Trebalo je nešto poduzeti.

Jezik C evoluirao je iz strukturiranog jezika u objektno orijentirani jezik - jezik zvan C ++. Zgodna stvar objektno orijentiranog jezika je što programerima daje mogućnost modeliranja stvarnih entiteta na prirodniji način korištenjem objekata.

Prije nekoliko godina Microsoft je objavio alat za programere koji su željeli stvoriti Windows programe pomoću C ++. Ovaj je proizvod postao poznat kao Visual C ++. Jedna od značajki predstavljenih s Visual C ++ bio je aplikacijski okvir poznat kao Microsoft Foundation Classes (MFC). MFC okvir je zbirka C ++ klasa, koju su napisali i testirali Microsoftovi programeri, a koja implementira puno osnovnih Windows funkcionalnosti. U MFC su implementirani mnogi softverski koncepti - od alatnih traka i statusnih traka do modela prikaza dokumenta koji se temelji na arhitekturi Model-View-Controller. Ideja MFC-a je uštedjeti vrijeme tijekom razvoja korištenjem MFC koda za veći dio aplikacije, a zatim proširivanjem MFC-a kako bi pružio jedinstvene mogućnosti te aplikacije - putem temeljnih objektno orijentiranih koncepata enkapsulacije, nasljeđivanja,i polimorfizam.

Međutim, razvoj softvera s MFC-om nije lak zadatak. Da bi napisali današnje Windows programe pomoću C ++ i MFC, programeri moraju dobro razumjeti objektno orijentirane koncepte programiranja, C ++ sintaksu i posebnosti, Windows API-je i MFC.

U idealnom slučaju, programeri trebaju jedan jezik i platformu koja im omogućuje pisanje aplikacija samo jednom, a zatim ih postavljanje svugdje. U pokušaju da udovolji ovoj potrebi, Sun je uz API-je jedinstvene za Javu (poput Java kartice) implementirao verzije mnogih Windows API-ja neutralnih za platformu. API-ji koji se bave upravljanjem datotekama, poštom, pomoći, multimedijom i sigurnošću imaju pandane u svijetu Windows. To rezultira jednom velikom pogodnošću za Windows programere: Umjesto da nauče puno Windows API-ja zajedno sa C ++ i MFC-om, programeri se mogu usredotočiti na učenje Jave i njezinih API-ja. Tada mogu koristiti Javu za razvoj Windows aplikacija. Evo kako.

API poziva

Dizajneri Jave smislili su mehanizam za primanje Java koda za razgovor s C ++ kodom. Ovaj mehanizam koristi zbirku C ++ API-ja poznatih kao Java Native Interface (JNI). Nekoliko je ovih API-ja okupljeno i zajednički su poznati kao API za pozivanje.

API pozivanja sastoji se od nekoliko JNI funkcija koje omogućavaju programeru da ugradi Java virtualni stroj (JVM) u proizvoljnu izvornu aplikaciju. S ugrađenim JVM-om, izvorna aplikacija ima pristup cijelom JVM-u upućivanjem JNI poziva.

JVM se kreira pozivom JNI_CreateJavaVM ()funkcije. Ova funkcija JDK1_1InitArgskao argument uzima pokazivač na strukturu. Ova struktura pruža zadane postavke za JVM. Zadane postavke mogu se nadjačati.

Da biste dobili zadane postavke JNI_GetDefaultJavaVMInitArgs (), mora se pozvati druga funkcija JNI,. Ova funkcija JDK1_1InitArgskao argument uzima pokazivač na strukturu. Tipični slijed poziva pojavljuje se u sljedećem popisu:

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

Polje verzije mora se postaviti prije pozivanja JNI_GetDefaultJavaVMInitArgs (). Ovo polje osigurava da aplikacija koristi ispravan JVM. Vrijednost 0x00010001 kodira glavni broj verzije potrebnog JVM-a u visokih 16 bitova i manji broj verzije u donjih 16 bitova. Vrijednost 0x00010001 znači da će bilo koji JVM čiji je broj verzije 1.1.2 ili veći biti ugrađen u aplikaciju.

Nekoliko zanimljivih polja obuhvaća JDK1_1InitArgsstrukturu, ali jedino polje koje ćemo spomenuti u ovom članku je polje poznato kao classpath. Ovo je polje važno jer JVM-u govori gdje se nalaze classes.zip i datoteke klase aplikacije.

Jednom kada je JDK1_1InitArgsstruktura inicijalizirana, JVM se može stvoriti pozivom na JNI_CreateJavaVM (), kao što je prikazano u sljedećem popisu:

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

U ovom trenutku JNI funkcionira FindClass ()i CallStaticVoidMethod ()bit će pozvan da pronađe odgovarajuću početnu klasu Java i početnu glavnu metodu.

Jednom kada JVM više nije potreban, on se uništava pozivom na DestroyJavaVM (), kao u sljedećem popisu.

jvm-> DestroyJavaVM () 

Pa, kako nam API poziva omogućuje stvaranje Win32 aplikacija pomoću Jave? Sljedeći primjer daje odgovor.

Primjer

Odlučio sam stvoriti konzolu Win32 sličnu PKZIP-u, ali moja bi aplikacija bila malo jednostavnija. Pružio bi samo mogućnost popisa svih datoteka u zip arhivi i izdvajanja datoteka. Moja bi se aplikacija pokrenula iz naredbenog retka koristeći sljedeću sintaksu:

c: \> zip [-x datoteka] zip 

pri čemu -xje zastavica ekstrakcije, filenaziv je datoteke za izdvajanje i zipnaziv je arhive sa ili bez zip nastavka.

Sljedeći popis prikazuje izvorni kod C ++ zip.cpp. Ovaj kôd implementira izvršni pokretački program ZIP. Ovaj pokretač učitava JVM, raščlanjuje argumente naredbenog retka, pronalazi ZIPdatoteku klase, smješta glavnu metodu unutar ZIPdatoteke klase, pokreće glavnu metodu (prosljeđivanje popisa argumenata ovoj metodi) i istovara JVM.

// ================================================== === // zip.cpp // // ZIP izvršni upravljački program // // Podržava Java virtualni stroj (JVM) 1.1.2 ili noviji // ================= ================================== #include #include #include #include #define BUFSIZE 80 // == ================================================ // Rukovatelj / / // Upravitelj konzole // // Zanemari sve pokušaje isključivanja aplikacije. // // Argumenti: // // dwCtrlType - vrsta upravljanja događajem // // Povratak: // // TRUE (zanemari događaj) // ================== ============================== BOOL rukovatelj (DWORD dwCtrlType) {return TRUE; } // ========================================= // glavna // // Zip Izvršna točka ulaza upravljačkog programa // // Argumenti: // // argc - broj argumenata naredbenog retka // argv - niz argumenata naredbenog retka // // Povratak:// // 0 (uspjeh) ili 1 (neuspjeh) // ===================================== ==== int glavni (int argc, char * argv []) {int i; jint ret; JNIEnv * env; JavaVM * jvm; jclass klazz; jmethodID sredina; JDK1_1InitArgs vm_args; char szBuffer [BUFSIZE], szClassPath [BUFSIZE * 2 + 15]; // Spriječiti isključivanje aplikacije zbog pritiska na tipke Ctrl-Break ili Ctrl-C, // klikovi gumba za zatvaranje prozora, odjava korisnika ili isključivanje sustava. SetConsoleCtrlHandler ((PHANDLER_ROUTINE) Rukovatelj, TRUE); // Nabavite zadane inicijalizacijske argumente za JVM verzije 1.1.2 ili noviju. vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); // Recite JVM-u gdje se mogu naći datoteke klase programa i classes.zip. GetPrivateProfileString ("CONFIG", "PATH", ".", SzBuffer, 80, "zip.ini"); wsprintf (szClassPath, "% s;% s \\ class.zip;", szBuffer, szBuffer); vm_args.classpath = szClassPath; // Pokušaj stvaranja JVM instance. if (((ret = JNI_CreateJavaVM (& jvm, & env, & vm_args)) NewStringUTF (" "); jobjectrayrb argc - 1, env-> FindClass ("java / lang / String"), jstr); for (i = 1; i NewStringUTF (argv [i])) == 0) {fprintf (stderr, "Nema memorije \ n "); return 1;} env-> SetObjectArrayElement (str_array, i - 1, jstr);} // Pokušaj lociranja zip klase. if ((clazz = env-> FindClass (" zip ")) == 0) {fprintf (stderr, "Ne mogu pronaći zip klasu. Izlaz ... \ n"); return 1;} // Pokušaj lociranja glavne metode zip klase. if ((mid = env-> GetStaticMethodID (clazz, "main", "([Ljava / lang / String;) V")) == 0) {fprintf (stderr, "Može 't locirajte glavnu metodu. Izlaz iz ... \ n "); return 1;} // Pokreni glavnu metodu. Env-> CallStaticVoidMethod (clazz, mid, str_array); // Uništi JVM instancu. Jvm-> DestroyJavaVM (); return 0;}

Obratite pažnju na poziv funkcije Win32 GetPrivateProfileString (). Ova funkcija traži datoteku pod nazivom zip.ini(koja bi se nalazila u direktoriju Windows - obično c: \ windows pod Windowsom 95 ili c: \ winnt pod Windowsom NT). Svrha ove datoteke je zadržati put na koji je instaliran ZIP program. JVM će na ovom mjestu potražiti datoteke class.zip i datoteke klasa aplikacija (bez obzira odakle se zove ZIP aplikacija).

Još jedna stavka koju treba primijetiti je poziv na SetConsoleCtrlHandler ()Win32 API. Ovaj API sprječava pritiske tipki Ctrl-C ili Ctrl-Break - uz ostale događaje - da zaustave aplikaciju prije nego što završi. To može, ali ne mora biti poželjno, ovisno o primjeni.

ZIP aplikacija napisana je na Javi. Korisnicima daje mogućnost pregledavanja sadržaja zip arhivskih datoteka, kao i mogućnost izdvajanja pojedinačnih datoteka iz tih arhiva. Sljedeći popis sadrži izvorni kod za ZIP.