Programmēšana

Java un Win32 apvienošana: jauns veids, kā attīstīt Windows lietojumprogrammas

Ziņu mediji pēdējās nedēļās ir pievērsuši uzmanību vairākiem apvienošanās gadījumiem. Bankas, automobiļu korporācijas un mazumtirdzniecības ķēdes ir paziņojušas, ka tās apvienojas. Vai varat iedomāties šoku, ja Sun Microsystems un Microsoft kādreiz izlems apvienoties? Nu, es nedomāju, ka mums vajadzētu aizturēt elpu. Es tomēr domāju, ka Sun un Microsoft varētu viens no otra iemācīties vienu vai divas lietas. Galu galā abi uzņēmumi ir izstrādājuši labus produktus - proti, Java un Win32. Manuprāt, Java mācīšanās līkne ir daudz īsāka nekā C ++ mācīšanās līkne. Tajā pašā laikā Win32 ir viens svarīgs iemesls, kāpēc Microsoft Windows 95 / NT darbojas uz daudziem miljoniem datoru. Šķiet tikai dabiski apvienot Java un Win32, lai izstrādātājiem dotu iespēju iegūt labākas Windows lietojumprogrammas īsākā laika posmā. Tas ir šī raksta uzmanības centrā.

Sākumā...

Pirmās Windows lietojumprogrammas tika rakstītas C valodā. Lai gan C bija piemērots mazām lietojumprogrammām, izstrādātājiem bija grūti izmantot šo valodu, lai organizētu lielākas lietojumprogrammas. Problēma ir vērsta ap Windows ziņojumapmaiņas modeli un to, ka C ir strukturēta, nevis objektorientēta valoda. Tradicionālās lietojumprogrammas, izmantojot C, izveidotu galveno logu un piešķirtu atzvanīšanas funkciju (pazīstama kā loga procedūra) uz šo logu. Ikreiz, kad ar šo logu notiek kādas sekas, Windows izsauc logam ziņojumu, izsaucot loga procedūru. Loga procedūra atbildētu, vispirms identificējot ziņojumu, izmantojot milzīgu pārsūtīšanas gadījuma paziņojumu, un pēc tam ziņojumu apstrādājot. Kā tas bieži notiek, stāvoklis būtu jāsaglabā, izmantojot lokālos statiskos mainīgos vai globālos mainīgos. Liela lietojumprogramma var radīt daudz šādu mainīgo. Šī paradigma labi darbojās mazākās lietojumprogrammās, taču izrādījās, ka tā kaitē lielākiem lietojumiem. Kaut kas bija jādara.

C valoda no strukturētas valodas pārtapa par objektorientētu valodu - valodu, ko sauc par C ++. Jauka lieta uz objektorientēto valodu ir tā, ka tā dod izstrādātājiem iespēju modelēt reālās pasaules vienības dabiskākā veidā, izmantojot objektus.

Pirms dažiem gadiem Microsoft izlaida rīku izstrādātājiem, kuri vēlējās izveidot Windows lietojumprogrammas, izmantojot C ++. Šis produkts kļuva pazīstams kā Visual C ++. Viena no funkcijām, kas tika ieviesta ar Visual C ++, bija lietojumprogrammu sistēma, kas pazīstama kā Microsoft Foundation Classes (MFC). MFC ietvars ir C ++ klašu kolekcija, ko uzrakstījuši un pārbaudījuši Microsoft izstrādātāji un kas ievieš daudz pamata Windows funkcionalitātes. MFC ir ieviesti daudzi programmatūras jēdzieni - sākot no rīkjoslām un statusa joslām līdz dokumentu skata modelim, kura pamatā ir Model-View-Controller arhitektūra. MFC ideja ir ietaupīt laiku izstrādes laikā, izmantojot MFC kodu lielākajai daļai lietojumprogrammu, un pēc tam paplašinot MFC, lai nodrošinātu šīs lietojumprogrammas unikālās iespējas - izmantojot objektīvos pamatkapsulācijas, mantojuma un polimorfisma jēdzienus.

Tomēr programmatūras izstrāde ar MFC nav viegls uzdevums. Lai rakstītu mūsdienu Windows lietojumprogrammas, izmantojot C ++ un MFC, izstrādātājiem ir labi jāpārzina objektorientētās programmēšanas koncepcijas, C ++ sintakse un īpatnības, Windows API un MFC.

Ideālā gadījumā izstrādātājiem ir nepieciešama viena valoda un platforma, kas ļauj viņiem tikai vienu reizi rakstīt lietojumprogrammas un pēc tam izvietot tās visur. Mēģinot apmierināt šo vajadzību, Sun papildus Java unikālajām API (piemēram, Java Card) ir ieviesis daudzām Windows API platformām neitrālas versijas. API, kas nodarbojas ar failu pārvaldību, pastu, palīdzību, multimediju un drošību, ir līdzīgi Windows pasaulē. Tā rezultātā ir viens liels ieguvums Windows izstrādātājiem: tā vietā, lai mācītos daudz Windows API kopā ar C ++ un MFC, izstrādātāji var koncentrēties uz Java un tās API apgūšanu. Tad viņi var izmantot Java, lai izstrādātu Windows lietojumprogrammas. Lūk, kā.

Uzaicināšanas API

Java dizaineri nāca klajā ar mehānismu, kā iegūt Java kodu sarunai ar C ++ kodu. Šis mehānisms izmanto C ++ API kolekciju, kas pazīstama kā Java vietējā saskarne (JNI). Vairākas no šīm saskarnēm ir apvienotas un kopā tiek sauktas par izsaukuma API.

Uzaicināšanas API sastāv no vairākām JNI funkcijām, kas ļauj izstrādātājam iegult Java virtuālo mašīnu (JVM) patvaļīgā vietējā lietojumprogrammā. Ar iegulto JVM vietējai lietojumprogrammai ir piekļuve visam JVM, veicot JNI zvanus.

JVM tiek izveidots, piezvanot uz JNI_CreateJavaVM () funkciju. Šī funkcija novirza rādītāju uz a JDK1_1InitArgs struktūra kā arguments. Šī struktūra nodrošina JVM noklusējuma iestatījumus. Noklusējumus var ignorēt.

Lai iegūtu noklusējuma iestatījumus, vēl viena JNI funkcija, JNI_GetDefaultJavaVMInitArgs (), jāzvana. Šī funkcija novirza rādītāju uz JDK1_1InitArgs struktūra kā arguments. Tipiska zvana secība parādās šādā sarakstā:

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

Versijas lauks ir jāiestata pirms zvanīšanas JNI_GetDefaultJavaVMInitArgs (). Šis lauks nodrošina, ka lietojumprogramma izmanto pareizo JVM. Vērtība 0x00010001 kodē vajadzīgā JVM galveno versijas numuru augstajos 16 bitos un mazās versijas numuru zemajos 16 bitos. 0x00010001 vērtība nozīmē, ka jebkurš JVM, kura versijas numurs ir 1.1.2 vai lielāks, tiks iegults lietojumprogrammā.

Vairākas interesantas jomas veido JDK1_1InitArgs struktūru, bet vienīgais lauks, kuru mēs pieminēsim šajā rakstā, ir lauks, kas pazīstams kā klases ceļš. Šis lauks ir svarīgs, jo tas norāda JVM, kur atrodas class.zip un lietojumprogrammas klases faili.

Kad JDK1_1InitArgs struktūra ir inicializēta, JVM var izveidot, izmantojot zvanu uz JNI_CreateJavaVM (), kā parādīts šādā sarakstā:

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

Šajā brīdī JNI darbojas FindClass () un CallStaticVoidMethod () tiks uzaicināts atrast atbilstošo Java sākuma klasi un sākuma galveno metodi.

Kad JVM vairs nav vajadzīgs, tas tiek iznīcināts ar zvanu uz IznīcinātJavaVM (), kā šajā sarakstā.

jvm-> IznīcinātJavaVM () 

Tātad, kā Invocation API ļauj mums izveidot Win32 lietojumprogrammas, izmantojot Java? Šis piemērs sniedz atbildi.

Piemērs

Es nolēmu izveidot Win32 konsoles lietojumprogrammu, kas līdzīga PKZIP, taču mana lietojumprogramma būtu nedaudz vienkāršāka. Tas tikai nodrošinātu iespēju visus failus ievietot ZIP arhīvā un iegūt failus. Mana lietojumprogramma tiks palaista no komandrindas, izmantojot šādu sintaksi:

c: \> zip [-x fails] zip 

ar kuru -x ir ieguves karogs, failu ir iegūstamā faila nosaukums un zip ir arhīva nosaukums ar rāvējslēdzēja paplašinājumu vai bez tā.

Šis saraksts parāda C ++ avota kodu zip.cpp. Šis kods ievieš ZIP izpildāmo draiveri. Šis draiveris ielādē JVM, parsē komandrindas argumentus, atrod ZIP klases failu, atrod galveno metodi ZIP klases failu, palaiž galveno metodi (argumentu saraksta nodošanu šai metodei) un izlādē JVM.

// ================================================== === // zip.cpp // // ZIP izpildāms draiveris // // Atbalsta Java virtuālo mašīnu (JVM) 1.1.2 vai jaunāku versiju // ================= ================================== # iekļaut # iekļaut # iekļaut # iekļaut # definēt BUFSIZE 80 // == =============================================== // // apdarinātājs / / // Konsoles vadības apstrādātājs // // Ignorēt visus mēģinājumus izslēgt lietojumprogrammu. Argumenti: // // dwCtrlType - vadības notikuma veids // // Return: // TRUE (ignorēt notikumu) // =================== ============================== BOOL Handler (DWORD dwCtrlType) {return TRUE; } // ======================================= // // galvenais // // Zip Izpildāmā draivera ievades punkts // // Argumenti: // // argc - komandrindas argumentu skaits // argv - komandrindas argumentu masīvs // // Return: // // 0 (panākumi) vai 1 (neveiksmes) / / ======================================= int galvenais (int argc, char * argv [ ]) {starp i; jint ret; JNIEnv * env; JavaVM * jvm; jclass clazz; jmethodID vidū; JDK1_1InitArgs vm_args; char szBuffer [BUFSIZE], szClassPath [BUFSIZE * 2 + 15]; // Novērsiet lietojumprogrammas izslēgšanu Ctrl-Break vai Ctrl-C taustiņu nospiešanas, // loga aizvēršanas pogas klikšķu, lietotāja atteikšanās vai sistēmas izslēgšanas dēļ. SetConsoleCtrlHandler ((PHANDLER_ROUTINE) Handler, TRUE); // Iegūt noklusējuma inicializācijas argumentus JVM 1.1.2 vai jaunākai versijai. vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); // Pastāstiet JVM, kur atrast lietojumprogrammu klases failus un class.zip. GetPrivateProfileString ("CONFIG", "PATH", ".", SzBuffer, 80, "zip.ini"); wsprintf (szClassPath, "% s;% s \ class.zip;", szBuffer, szBuffer); vm_args.classpath = szClassPath; // Mēģinājums izveidot JVM instanci. if ((ret = JNI_CreateJavaVM (& jvm, & env, & vm_args)) NewStringUTF (""); jobjectArray str_array = env-> NewObjectArray (argc - 1, env-> FindClass ("java / lang / String"), jstr); (i = 1; i NewStringUTF (argv [i])) == 0) {fprintf (stderr, "Trūkst atmiņas \ n"); atgriezties 1; } env-> SetObjectArrayElement (str_array, i - 1, jstr); } // Mēģinājums atrast zip klasi. if ((clazz = env-> FindClass ("zip")) == 0) {fprintf (stderr, "Nevar atrast zip klasi. Iziet ... \ n"); atgriezties 1; } // Mēģinājums atrast zip klases galveno metodi. if ((mid = env-> GetStaticMethodID (clazz, "main", "([Ljava / lang / String;) V")) == 0) {fprintf (stderr, "Nevar atrast galveno metodi. Iziet. .. \ n "); atgriezties 1; } // Palaist galveno metodi. env-> CallStaticVoidMethod (clazz, mid, str_array); // Iznīcināt JVM instanci. jvm-> IznīcinātJavaVM (); atgriešanās 0; } 

Ievērojiet zvanu uz Win32 GetPrivateProfileString () funkciju. Šī funkcija meklē failu ar nosaukumu zip.ini (kas atrastos Windows direktorijā - parasti c: \ windows zem Windows 95 vai c: \ winnt zem Windows NT). Šī faila mērķis ir turēt ceļu, kur ir instalēta ZIP lietojumprogramma. Šajā vietā JVM meklēs class.zip un lietojumprogrammu klases failus (neatkarīgi no tā, no kurienes tiek izsaukta ZIP lietojumprogramma).

Vēl viena piezīme, kas jāņem vērā, ir zvans uz SetConsoleCtrlHandler () Win32 API. Šī API neļauj Ctrl-C vai Ctrl-Break taustiņu nospiešanai papildus citiem notikumiem apturēt lietojumprogrammu pirms tās pabeigšanas. Tas var būt vai nav vēlams, atkarībā no lietojuma.

ZIP programma ir rakstīta Java valodā. Tas dod lietotājiem iespēju apskatīt zip arhīvu failu saturu, kā arī iespēju izvilkt atsevišķus failus no šiem arhīviem. Šajā sarakstā ir ZIP avota kods.

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