Menggabungkan Java dan Win32: Cara baru untuk mengembangkan aplikasi Windows

Media berita telah memfokuskan perhatian pada sejumlah merger dalam beberapa pekan terakhir. Bank, perusahaan otomotif, dan jaringan ritel telah mengumumkan bahwa mereka akan bergabung. Dapatkah Anda membayangkan keterkejutan jika Sun Microsystems dan Microsoft memutuskan untuk bergabung? Yah, menurutku kita tidak harus menahan nafas. Namun, menurut saya, Sun dan Microsoft dapat belajar satu atau dua hal dari satu sama lain. Bagaimanapun, kedua perusahaan telah mengembangkan produk yang bagus - yaitu Java dan Win32. Menurut saya, kurva pembelajaran Java jauh lebih pendek daripada kurva pembelajaran C ++. Pada saat yang sama, Win32 adalah salah satu alasan penting mengapa Microsoft menjalankan Windows 95 / NT pada sekian juta PC. Tampaknya wajar untuk menggabungkan Java dan Win32 untuk memberi pengembang keunggulan yang mereka butuhkan untuk membuat aplikasi Windows yang lebih baik dalam waktu yang lebih singkat. Itulah fokus artikel ini.

Pada awalnya...

Aplikasi Windows pertama ditulis dalam bahasa C. Meskipun C tidak masalah untuk aplikasi kecil, pengembang merasa kesulitan menggunakan bahasa ini untuk mengatur aplikasi yang lebih besar. Masalahnya berpusat di sekitar model olahpesan Windows dan fakta bahwa C adalah bahasa yang terstruktur daripada bahasa berorientasi objek. Aplikasi tradisional yang menggunakan C akan membuat jendela utama dan menetapkan fungsi panggilan balik (dikenal sebagai prosedur jendela) ke jendela ini. Kapan pun sesuatu yang berdampak terjadi pada jendela ini, Windows akan mengirimkan pesan ke jendela dengan memanggil prosedur jendela. Prosedur jendela akan merespons dengan terlebih dahulu mengidentifikasi pesan melalui pernyataan switch-case yang besar dan kemudian memproses pesan tersebut. Seperti yang sering terjadi, status perlu disimpan melalui variabel statis lokal atau variabel global. Aplikasi yang besar dapat menghasilkan banyak variabel seperti itu. Paradigma ini bekerja dengan baik untuk aplikasi yang lebih kecil tetapi terbukti merugikan aplikasi yang lebih besar. Sesuatu harus dilakukan.

Bahasa C berkembang dari bahasa terstruktur menjadi bahasa berorientasi objek - bahasa yang disebut C ++. Hal yang menyenangkan tentang bahasa berorientasi objek adalah ia memberi pengembang kemampuan untuk memodelkan entitas dunia nyata dengan cara yang lebih alami dengan menggunakan objek.

Beberapa tahun yang lalu, Microsoft merilis alat untuk pengembang yang ingin membuat aplikasi Windows menggunakan C ++. Produk ini kemudian dikenal sebagai Visual C ++. Salah satu fitur yang diperkenalkan dengan Visual C ++ adalah kerangka kerja aplikasi yang dikenal sebagai Microsoft Foundation Classes (MFC). Kerangka kerja MFC adalah kumpulan kelas C ++, ditulis dan diuji oleh pengembang Microsoft, yang mengimplementasikan banyak fungsi dasar Windows. Banyak konsep perangkat lunak - dari bilah alat dan bilah status hingga model tampilan dokumen berdasarkan arsitektur Model-View-Controller - telah diterapkan di MFC. Ide di balik MFC adalah untuk menghemat waktu selama pengembangan dengan menggunakan kode MFC untuk sebagian besar aplikasi dan kemudian memperluas MFC untuk menyediakan kemampuan unik aplikasi itu - melalui konsep dasar berorientasi objek enkapsulasi, pewarisan,dan polimorfisme.

Namun, mengembangkan perangkat lunak dengan MFC bukanlah tugas yang mudah. Untuk menulis aplikasi Windows saat ini menggunakan C ++ dan MFC, pengembang harus memiliki pemahaman yang baik tentang konsep pemrograman berorientasi objek, sintaks dan kekhasan C ++, Windows API, dan MFC.

Idealnya, pengembang membutuhkan satu bahasa dan platform yang memungkinkan mereka untuk menulis aplikasi hanya sekali dan kemudian menerapkannya di mana-mana. Dalam upaya memenuhi kebutuhan ini, Sun telah mengimplementasikan versi platform-netral dari banyak Windows API selain API yang unik untuk Java (seperti Java Card). API yang berhubungan dengan manajemen file, surat, bantuan, multimedia, dan keamanan memiliki kesamaan di dunia Windows. Ini menghasilkan satu manfaat utama bagi pengembang Windows: Alih-alih mempelajari banyak API Windows bersama dengan C ++ dan MFC, pengembang dapat fokus mempelajari Java dan API-nya. Kemudian, mereka dapat menggunakan Java untuk mengembangkan aplikasi Windows. Begini caranya.

API Panggilan

Perancang Java datang dengan mekanisme untuk mendapatkan kode Java untuk berbicara dengan kode C ++. Mekanisme ini menggunakan kumpulan C ++ API yang dikenal sebagai Java Native Interface (JNI). Beberapa dari API ini telah digabungkan, dan secara kolektif dikenal sebagai API Panggilan.

API Panggilan terdiri dari beberapa fungsi JNI yang memungkinkan pengembang untuk menyematkan mesin virtual Java (JVM) ke dalam aplikasi asli arbitrer. Dengan JVM tersemat, aplikasi asli memiliki akses ke seluruh JVM dengan melakukan panggilan JNI.

JVM dibuat melalui panggilan ke JNI_CreateJavaVM ()fungsi tersebut. Fungsi ini membawa penunjuk ke JDK1_1InitArgsstruktur sebagai argumen. Struktur ini menyediakan pengaturan default untuk JVM. Default dapat diganti.

Untuk mendapatkan pengaturan default, fungsi JNI lainnya JNI_GetDefaultJavaVMInitArgs (),, harus dipanggil. Fungsi ini mengambil penunjuk ke JDK1_1InitArgsstruktur sebagai argumen. Urutan panggilan tipikal muncul dalam daftar berikut:

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

Bidang versi harus disetel sebelum menelepon JNI_GetDefaultJavaVMInitArgs (). Bidang ini memastikan bahwa JVM yang benar digunakan oleh aplikasi. Nilai 0x00010001 mengkodekan nomor versi utama dari JVM yang diperlukan dalam 16 bit tinggi dan nomor versi kecil di 16 bit rendah. Nilai 0x00010001 berarti bahwa setiap JVM yang nomor versinya 1.1.2 atau lebih tinggi akan disematkan ke dalam aplikasi.

Beberapa bidang menarik terdiri dari JDK1_1InitArgsstruktur, tetapi satu-satunya bidang yang akan kami sebutkan di artikel ini adalah bidang yang dikenal sebagai classpath. Bidang ini penting karena memberi tahu JVM di mana class.zip dan file kelas aplikasi berada.

Setelah JDK1_1InitArgsstruktur diinisialisasi, JVM dapat dibuat melalui panggilan ke JNI_CreateJavaVM (), seperti yang ditunjukkan pada daftar berikut:

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

Pada titik ini, JNI berfungsi FindClass ()dan CallStaticVoidMethod ()akan dipanggil untuk menemukan kelas awal Java yang sesuai dan metode utama awal.

Setelah JVM tidak lagi diperlukan, JVM dihancurkan dengan panggilan ke DestroyJavaVM (), seperti dalam daftar berikut.

jvm-> HancurkanJavaVM () 

Jadi, bagaimana Invocation API memungkinkan kita membuat aplikasi Win32 menggunakan Java? Contoh berikut memberikan jawabannya.

Sebuah contoh

Saya memutuskan untuk membuat aplikasi konsol Win32 yang mirip dengan PKZIP, tetapi aplikasi saya akan sedikit lebih sederhana. Ini hanya akan memberikan kemampuan untuk membuat daftar semua file dalam arsip zip dan mengekstrak file. Aplikasi saya akan diluncurkan dari baris perintah menggunakan sintaks berikut:

c: \> zip [-x file] zip 

dimana -xbendera ekstraksi, fileadalah nama file yang akan diekstrak, dan zipmerupakan nama arsip dengan atau tanpa ekstensi zip.

Daftar berikut menunjukkan kode sumber C ++ zip.cpp. Kode ini mengimplementasikan driver yang dapat dieksekusi ZIP. Driver ini memuat JVM, mengurai argumen baris perintah, menemukan ZIPfile kelas, menemukan metode utama dalam ZIPfile kelas, meluncurkan metode utama (meneruskan daftar argumen ke metode ini), dan membongkar JVM.

// ================================================ === // zip.cpp // // ZIP Executable Driver // // Mendukung Java Virtual Machine (JVM) 1.1.2 atau lebih tinggi // ================= ================================== #include #include #include #include #define BUFSIZE 80 // == ============================================== // Handler / / // Console Control Handler // // Abaikan semua percobaan untuk mematikan aplikasi. // // Argumen: // // dwCtrlType - control event type // // Return: // // TRUE (abaikan event) // ================== ============================== BOOL Handler (DWORD dwCtrlType) {return TRUE; } // ======================================= // utama // // Zip Titik Masuk Pengemudi yang Dapat Dijalankan // // Argumen: // // argc - jumlah argumen baris perintah // argv - larik argumen baris perintah // // Kembali:// // 0 (berhasil) atau 1 (kegagalan) // =================================== ==== 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]; // Cegah aplikasi agar tidak mati karena Ctrl-Break atau Ctrl-C menekan tombol, // klik tombol tutup jendela, logoff pengguna, atau sistem mati. SetConsoleCtrlHandler ((PHANDLER_ROUTINE) Penangan, BENAR); // Dapatkan argumen inisialisasi default untuk JVM versi 1.1.2 atau lebih tinggi. vm_args.version = 0x00010001; JNI_GetDefaultJavaVMInitArgs (& vm_args); // Beri tahu JVM di mana menemukan file kelas aplikasi dan kelas.zip. GetPrivateProfileString ("CONFIG", "PATH", ".", SzBuffer, 80, "zip.ini"); wsprintf (szClassPath, "% s;% s \\ kelas.zip;", szBuffer, szBuffer); vm_args.classpath = szClassPath; // Mencoba membuat instance JVM. if ((ret = JNI_CreateJavaVM (& jvm, & env, & vm_args)) NewStringUTF (" "); jobjectArray strA_array (= env argc - 1, env-> FindClass ("java / lang / String"), jstr); untuk (i = 1; i NewStringUTF (argv [i])) == 0) {fprintf (stderr, "Habis memori \ n "); return 1;} env-> SetObjectArrayElement (str_array, i - 1, jstr);} // Mencoba menemukan kelas zip. if ((clazz = env-> FindClass (" zip ")) == 0) {fprintf (stderr, "Tidak dapat menemukan kelas zip. Keluar ... \ n"); return 1;} // Mencoba menemukan metode utama kelas zip. if ((mid = env-> GetStaticMethodID (clazz, "main", "([Ljava / lang / String;) V")) == 0) {fprintf (stderr, "Can 't temukan metode utama. Keluar ... \ n "); return 1;} // Luncurkan metode utama. Env-> CallStaticVoidMethod (clazz, mid, str_array); // Hancurkan instance JVM. Jvm-> DestroyJavaVM (); return 0;}

Perhatikan panggilan ke GetPrivateProfileString ()fungsi Win32 . Fungsi ini mencari file bernama zip.ini(yang akan ditempatkan di direktori Windows - biasanya c: \ windows di bawah Windows 95 atau c: \ winnt di Windows NT). Tujuan dari file ini adalah untuk menyimpan jalur tempat aplikasi ZIP diinstal. JVM akan mencari di lokasi ini untuk file kelas kelas dan aplikasi (tidak peduli dari mana aplikasi ZIP dipanggil).

Item lain yang perlu diperhatikan adalah panggilan ke SetConsoleCtrlHandler ()Win32 API. API ini mencegah penekanan tombol Ctrl-C atau Ctrl-Break - selain peristiwa lain - menghentikan aplikasi sebelum selesai. Ini mungkin diinginkan atau tidak, tergantung pada aplikasinya.

Aplikasi ZIP ditulis dalam Java. Ini memberi pengguna kemampuan untuk melihat konten file arsip zip, serta kemampuan untuk mengekstrak file individual dari arsip ini. Daftar berikut berisi kode sumber ke ZIP.