Programmering

Sammenslåing av Java og Win32: En ny måte å utvikle Windows-applikasjoner på

Nyhetsmediene har fokusert på en rekke fusjoner de siste ukene. Banker, bilforetak og detaljhandelskjeder har kunngjort at de smelter sammen. Kan du forestille deg sjokket hvis Sun Microsystems og Microsoft noen gang bestemmer seg for å slå seg sammen? Jeg tror ikke vi skal holde pusten. Jeg tror imidlertid at Sun og Microsoft kunne lære en ting eller to av hverandre. Tross alt har begge selskapene utviklet gode produkter - nemlig Java og Win32. Etter min mening er Java-læringskurven mye kortere enn C ++ læringskurven. Samtidig er Win32 en viktig årsak til at Microsoft har Windows 95 / NT som kjører på noen få millioner PCer. Det virker bare naturlig å slå sammen Java og Win32 for å gi utviklere muligheten de trenger for å lage bedre Windows-applikasjoner på kortere tid. Det er fokus for denne artikkelen.

I begynnelsen...

De første Windows-applikasjonene ble skrevet på C-språket. Mens C var greit for små applikasjoner, fant utviklere det vanskelig å bruke dette språket for å organisere større applikasjoner. Problemet var sentrert rundt Windows meldingsmodell og det faktum at C er et strukturert snarere enn et objektorientert språk. Tradisjonelle applikasjoner som bruker C, vil opprette et hovedvindu og tilordne en tilbakeringingsfunksjon (kjent som a vindusprosedyre) til dette vinduet. Når noe av dette skjedde med dette vinduet, avbrøt Windows en melding til vinduet ved å ringe vindusprosedyren. Vindusprosedyren vil svare ved først å identifisere meldingen via en enorm switch-case uttalelse og deretter behandle meldingen. Som ofte er tilfellet, vil staten måtte lagres via lokale statiske variabler eller globale variabler. Et stort program kan resultere i mange slike variabler. Dette paradigmet fungerte bra for mindre applikasjoner, men viste seg å være skadelig for større applikasjoner. Noe måtte gjøres.

C-språket utviklet seg fra et strukturert språk til et objektorientert språk - et språk som heter C ++. Det fine med et objektorientert språk er at det gir utviklere muligheten til å modellere virkelige enheter på en mer naturlig måte ved å bruke objekter.

For noen år siden ga Microsoft ut et verktøy for utviklere som ønsket å lage Windows-applikasjoner ved hjelp av C ++. Dette produktet ble kjent som Visual C ++. En av funksjonene introdusert med Visual C ++ var et applikasjonsrammeverk kjent som Microsoft Foundation Classes (MFC). MFC-rammeverket er en samling C ++ -klasser, skrevet og testet av Microsofts utviklere, som implementerer mye grunnleggende Windows-funksjonalitet. Mange programvarekonsepter - fra verktøylinjer og statusfelt til en dokumentvisningsmodell basert på Model-View-Controller-arkitekturen - er implementert i MFC. Ideen bak MFC er å spare tid under utvikling ved å bruke MFC-kode for det meste av applikasjonen, og deretter utvide MFC for å gi applikasjonens unike evner - via de grunnleggende objektorienterte konseptene innkapsling, arv og polymorfisme.

Å utvikle programvare med MFC er imidlertid ikke en enkel oppgave. For å kunne skrive dagens Windows-applikasjoner ved bruk av C ++ og MFC, må utviklere ha god forståelse av objektorienterte programmeringskonsepter, C ++ syntaks og særegenheter, Windows API-er og MFC.

Ideelt sett trenger utviklere et enkelt språk og en plattform som lar dem skrive applikasjoner bare en gang og deretter distribuere dem overalt. I et forsøk på å dekke dette behovet har Sun implementert plattformnøytrale versjoner av mange Windows APIer i tillegg til APIer som er unike for Java (for eksempel Java Card). API-er som håndterer filhåndtering, e-post, hjelp, multimedia og sikkerhet har kolleger i Windows-verdenen. Dette resulterer i en stor fordel for Windows-utviklere: I stedet for å lære mange Windows API-er sammen med C ++ og MFC, kan utviklere fokusere på å lære Java og dets API-er. Deretter kan de bruke Java til å utvikle Windows-applikasjoner. Dette er hvordan.

Invocation API

Designerne av Java kom opp med en mekanisme for å få Java-kode til å snakke med C ++ -koden. Denne mekanismen bruker en samling C ++ API-er kjent som Java Native Interface (JNI). Flere av disse API-ene er samlet, og er samlet kjent som Invocation API.

Invocation API består av flere JNI-funksjoner som gjør det mulig for utvikleren å legge inn den virtuelle Java-maskinen (JVM) i et vilkårlig innfødt program. Med JVM innebygd har den opprinnelige applikasjonen tilgang til hele JVM ved å ringe JNI.

JVM opprettes via en samtale til JNI_CreateJavaVM () funksjon. Denne funksjonen tar en peker til a JDK1_1InitArgs struktur som argument. Denne strukturen gir standardinnstillinger for JVM. Standardinnstillingene kan overstyres.

For å få standardinnstillingene, en annen JNI-funksjon, JNI_GetDefaultJavaVMInitArgs (), må kalles. Denne funksjonen tar en peker til JDK1_1InitArgs struktur som argument. En typisk anropssekvens vises i følgende liste:

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

Versjonsfeltet må angis før du ringer JNI_GetDefaultJavaVMInitArgs (). Dette feltet sikrer at riktig JVM brukes av applikasjonen. En verdi på 0x00010001 koder hovedversjonsnummeret til den nødvendige JVM i de høye 16 bitene og det mindre versjonsnummeret i de lave 16 bitene. Verdien 0x00010001 betyr at enhver JVM med versjonsnummer er 1.1.2 eller høyere vil bli innebygd i applikasjonen.

Flere interessante felt består av JDK1_1InitArgs struktur, men det eneste feltet vi nevner i denne artikkelen er feltet kjent som klassesti. Dette feltet er viktig fordi det forteller JVM hvor classes.zip og programklassefilene ligger.

Først når JDK1_1InitArgs strukturen er initialisert, kan JVM opprettes via en samtale til JNI_CreateJavaVM (), som vist i følgende liste:

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

På dette punktet fungerer JNI FindClass () og CallStaticVoidMethod () vil bli kalt for å finne riktig Java-startklasse og startmetoden.

Når JVM ikke lenger er nødvendig, blir den ødelagt av en samtale til DestroyJavaVM (), som i følgende liste.

jvm-> DestroyJavaVM () 

Så hvordan tillater Invocation API oss å lage Win32-applikasjoner ved hjelp av Java? Følgende eksempel gir et svar.

Et eksempel

Jeg bestemte meg for å lage et Win32-konsollprogram som ligner på PKZIP, men applikasjonen min ville være litt enklere. Det gir bare muligheten til å liste opp alle filene i et zip-arkiv og pakke ut filer. Søknaden min vil bli lansert fra kommandolinjen ved hjelp av følgende syntaks:

c: \> zip [-x fil] zip 

hvorved -x er utvinningsflagget, fil er navnet på filen som skal pakkes ut, og glidelås er navnet på arkivet med eller uten zip-utvidelse.

Følgende liste viser C ++ kildekoden zip.cpp. Denne koden implementerer ZIP-kjørbar driver. Denne driveren laster JVM, analyserer kommandolinjeargumentene, lokaliserer glidelås klassefil, lokaliserer hovedmetoden i glidelås klassefil, starter hovedmetoden (sender argumentlisten til denne metoden) og laster ut JVM.

// ==================================================== === // zip.cpp // // ZIP kjørbar driver // // Støtter Java Virtual Machine (JVM) 1.1.2 eller høyere // ================== =================================== # inkluderer # inkluderer # inkluderer # inkluderer # definer BUFSIZE 80 // == ================================================ // Handler / / // Console Control Handler // // Ignorer alle forsøk på å avslutte applikasjonen. // // Argumenter: // // dwCtrlType - kontrollhendelsestype // // Return: // // TRUE (ignorere hendelse) // ==================== ================================ BOOL Handler (DWORD dwCtrlType) {retur SANT; } // ========================================== // // // Zip Kjørbart driverinngangspunkt // // Argumenter: // // argc - antall kommandolinjeargumenter // argv - matrise med kommandolinjeargumenter // // Return: // // 0 (suksess) eller 1 (feil) / / ========================================= 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]; // Forhindre at applikasjonen stenges på grunn av Ctrl-Break eller Ctrl-C tastetrykk, // vindu lukkeknapper, brukeravlogging eller systemavstenging. SetConsoleCtrlHandler ((PHANDLER_ROUTINE) Handler, TRUE); // Få standard initialiseringsargumenter for JVM versjon 1.1.2 eller nyere. vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); // Fortell JVM hvor du finner programklassefilene og classes.zip. GetPrivateProfileString ("CONFIG", "PATH", ".", SzBuffer, 80, "zip.ini"); wsprintf (szClassPath, "% s;% s \ classes.zip;", szBuffer, szBuffer); vm_args.classpath = szClassPath; // Forsøk på å opprette en JVM-forekomst. hvis ((ret = JNI_CreateJavaVM (& jvm, & env, & vm_args)) NewStringUTF (""); jobjectArray str_array = env-> NewObjectArray (argc - 1, env-> FindClass ("java / lang / String"), jstr); for (i = 1; i NewStringUTF (argv [i])) == 0) {fprintf (stderr, "Out of memory \ n"); retur 1; } env-> SetObjectArrayElement (str_array, i - 1, jstr); } // Forsøk på å finne zip-klasse. hvis ((clazz = env-> FindClass ("zip")) == 0) {fprintf (stderr, "Can't find the zip class. Exiting ... \ n"); retur 1; } // Forsøk å finne hovedmetoden for zip-klassen. if ((mid = env-> GetStaticMethodID (clazz, "main", "([Ljava / lang / String;) V")) == 0) {fprintf (stderr, "Can't find the main method. Exiting. .. \ n "); retur 1; } // Start hovedmetode. env-> CallStaticVoidMethod (clazz, mid, str_array); // Ødelegge JVM-forekomsten. jvm-> DestroyJavaVM (); retur 0; } 

Legg merke til samtalen til Win32 GetPrivateProfileString () funksjon. Denne funksjonen ser etter en fil som heter zip.ini (som ligger i Windows-katalogen - vanligvis c: \ windows under Windows 95 eller c: \ winnt under Windows NT). Hensikten med denne filen er å holde banen der ZIP-applikasjonen er installert. JVM vil se på dette stedet etter classes.zip og programklassefiler (uansett hvor ZIP-applikasjonen kalles fra).

Et annet element å merke seg er en samtale til SetConsoleCtrlHandler () Win32 API. Denne API forhindrer Ctrl-C eller Ctrl-Break tastetrykk - i tillegg til andre hendelser - fra å stoppe applikasjonen før den er ferdig. Dette kan eller ikke kan være ønskelig, avhengig av applikasjonen.

ZIP-applikasjonen er skrevet på Java. Det gir brukerne muligheten til å se innholdet i zip-arkivfiler, samt muligheten til å trekke ut individuelle filer fra disse arkivene. Følgende oppføring inneholder kildekoden til ZIP.

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