Pernahkah Anda menggunakan Adobe Photoshop? Untuk orang awam, plugin hanyalah blok kode yang disediakan untuk aplikasi dari luar (misalnya, dalam DLL). Perbedaan antara plugin dan DLL normal adalah bahwa plugin memiliki kemampuan untuk memperluas fungsionalitas aplikasi induk. Misalnya, Photoshop sendiri tidak memiliki sejumlah besar fungsi pemrosesan gambar. Penambahan plug-in memberikan efek yang luar biasa seperti blur, spot, dan semua gaya lainnya, dan tidak ada yang memiliki aplikasi induk itu sendiri.
Ini sangat baik untuk program pemrosesan gambar, tetapi mengapa Anda perlu menghabiskan banyak upaya untuk menyelesaikan aplikasi komersial yang mendukung plugin? Misalkan, mari kita beri contoh, aplikasi Anda akan menghasilkan beberapa laporan. Pelanggan Anda pasti akan terus meminta pembaruan atau menambahkan laporan baru. Anda dapat menggunakan generator laporan eksternal seperti Report Smith, yang merupakan solusi yang tidak terlalu seperti yang sangat sangat, memerlukan penerbitan file tambahan, pelatihan tambahan untuk pengguna, dan sebagainya. Anda juga dapat menggunakan QuickReport, tetapi ini akan menempatkan Anda dalam Nightmare kontrol versi - jika Anda ingin membangun kembali aplikasi Anda setiap kali Anda mengubah font.
Namun, selama Anda membuat laporan ke plugin, Anda dapat menggunakannya. Butuh laporan baru? Tidak masalah, cukup instal DLL dan Anda akan melihatnya lain kali aplikasi dimulai. Contoh lain adalah aplikasi yang memproses data dari perangkat eksternal (seperti pemindai barcode). Dengan menulis setiap antarmuka perangkat pemrosesan rutin sebagai plug-in, Anda dapat mencapai skalabilitas maksimum tanpa membuat perubahan pada aplikasi induk.
Memulai
Hal terpenting sebelum Anda mulai menulis kode adalah mencari tahu fitur apa yang perlu diperluas. Ini karena plugin berinteraksi dengan aplikasi induk melalui antarmuka tertentu, yang akan ditentukan sesuai dengan kebutuhan Anda. Pada artikel ini, kami akan membangun 3 plugin untuk menampilkan beberapa cara plugin berinteraksi dengan aplikasi induk.
Kami akan membuat plugin menjadi DLL. Namun, sebelum melakukan ini, kita harus membuat shell untuk memuat dan mengujinya. Gambar 1 menunjukkan program uji setelah plug-in pertama dimuat. Plugin pertama tidak mencapai sesuatu yang besar, dan pada kenyataannya, yang dilakukannya hanyalah mengembalikan string yang menggambarkan dirinya sendiri. Namun, ini mengkonfirmasi poin penting-ini akan berfungsi dengan baik dengan atau tanpa aplikasi plug-in. Jika tidak ada plug-in, itu tidak akan muncul dalam daftar plug-in yang diinstal, tetapi aplikasi masih dapat melakukan fungsi secara normal.
Satu-satunya perbedaan antara plug-in shell kami dan aplikasi normal adalah unit sharemem dalam file sumber proyek yang muncul dalam klausa penggunaan dan kode yang memuat file plug-in. Aplikasi apa pun yang melewati parameter string antara dirinya dan unit Child DLL? Untuk menguji shell ini, Anda perlu menyalin file delphimm.dll dari direktori Delphi/bin ke jalur yang terkandung dalam variabel lingkungan jalur atau direktori tempat aplikasi berada. File tersebut juga harus didistribusikan pada saat yang sama ketika versi final dirilis.
Plug-in dimuat ke dalam cangkang uji ini melalui proses Loadplugins, yang disebut dalam acara FormCreate di jendela utama, lihat Gambar 2. Proses ini menggunakan fungsi FindFirst dan FindNext untuk menemukan file plugin di direktori tempat aplikasi berada. Setelah menemukan file, gunakan proses Loadplugins yang ditunjukkan pada Gambar 3 untuk memuatnya.
{Temukan file plugin di direktori aplikasi}
Prosedur tfrmmain.loadplugins;
var
sr: tsearchrec;
Path: String;
Ditemukan: Integer;
Mulai
Path: = ExtractFilePath (Application.Exename);
mencoba
Ditemukan: = findFirst (path + cplugin_mask, 0, sr);
Sedangkan ditemukan = 0 Mulai
Loadplugin (sr);
Ditemukan: = FindNext (SR);
akhir;
Akhirnya
Findclose (sr);
akhir;
akhir;
{Muat plugin yang ditentukan.
Prosedur tfrmmain.loadplugin (sr: tsearchrec);
var
Deskripsi: String;
Libhandle: integer;
GambaranProc: tplugindeScribe;
Mulai
Libhandle: = loadLibrary (pchar (sr.name));
Jika libhandle $#@60; $#@62;
Mulai
Gambaran: = getProcaddress (libhandle, cplugin_describe);
Jika ditugaskan (dijelaskan) lalu
DeskripsiProc (Deskripsi);
memplugins.lines.add (deskripsi);
akhir
kalau tidak
Mulai
MessagedLg ('File "' + Sr.Name + '" bukan plug-in yang valid.',
mtinformation, [mbok], 0);
akhir;
akhir
kalau tidak
MessagedLG ('Terjadi kesalahan memuat plug-in "' +
sr.name + '".', Mterror, [mbok], 0);
akhir;
Metode Loadplugin menunjukkan inti dari mekanisme plug-in. Pertama, plugin ini ditulis sebagai DLL. Kedua, dimuat secara dinamis melalui LoadLibrary API. Setelah DLL dimuat, kita membutuhkan cara untuk mengakses prosedur dan fungsi yang dikandungnya. Panggilan API GetProcaddress menyediakan mekanisme ini, yang mengembalikan pointer ke rutin yang diperlukan. Dalam demonstrasi sederhana kami, plugin hanya berisi prosedur yang disebut gambaran yang ditentukan oleh cplugin_describe yang konstan (kasus nama prosedur sangat penting, dan nama yang diteruskan ke GetProcaddress harus persis sama dengan nama rutin yang termasuk dalam DLL) . Jika tidak ada rutinitas yang diminta ditemukan di DLL, GetProcaddree akan mengembalikan nol, jadi Anda akan setuju untuk menggunakan fungsi yang ditugaskan untuk menentukan nilai pengembalian.
Untuk menyimpan pointer ke fungsi dengan cara yang mudah digunakan, perlu untuk membuat jenis tertentu untuk variabel yang digunakan. Perhatikan bahwa nilai pengembalian GetProcaddress disimpan dalam variabel, dideskripsikan, milik tipe TplugindeScribe. Inilah pernyataannya:
jenis
Tplugindescribe = Prosedur (var desc: string);
Karena prosedur ada di dalam DLL, ia mengkompilasi semua rutinitas ekspor melalui konversi panggilan standar, sehingga indikator STDCall diperlukan. Proses ini menggunakan parameter VAR, yang berisi deskripsi plugin saat proses kembali.
Untuk memanggil proses yang baru saja Anda peroleh, cukup gunakan variabel yang menyimpan alamat sebagai nama proses, diikuti oleh parameter apa pun. Dalam kasus kami, pernyataan itu:
DeskripsiProc (Deskripsi)
Proses deskripsi yang diperoleh dalam plug-in akan dipanggil dan variabel deskripsi diisi dengan string yang menggambarkan fungsionalitas plug-in.
Plug-in konstruksi
Kami telah membuat aplikasi induk, dan sekarang saatnya untuk membuat plugin yang ingin kami muat. File plugin adalah DLL DLPHI standar, jadi kami membuat proyek DLL baru dari Delphi IDE dan menyimpannya. Karena fungsi plug-in yang diekspor akan menggunakan parameter string, unit Sharemen harus ditempatkan terlebih dahulu dalam klausa penggunaan proyek. Gambar 4 mencantumkan file sumber proyek plug-in sederhana kami.
penggunaan
Sharemem, sysutils, kelas,
utama di 'Main.pas';
{$ E plg.}
ekspor
MenggambarkanPlugin;
Mulai
akhir.
Meskipun plugin adalah file DLL, tidak perlu memberikan ekstensi .dll. Bahkan, satu alasan cukup untuk memberi kita alasan untuk mengubah ekstensi: ketika aplikasi induk mencari file yang akan dimuat, ekstensi baru dapat berfungsi sebagai topeng file tertentu. Dengan menggunakan ekstensi lain (contoh kami menggunakan *.plg), Anda bisa agak yakin bahwa aplikasi hanya akan memuat file yang sesuai. Compile Indicator $ X dapat mencapai perubahan ini, atau Anda dapat mengatur ekstensi melalui halaman aplikasi kotak dialog Opsi Proyek.
Kode untuk plugin contoh pertama sangat sederhana. Gambar 5 menunjukkan kode yang terkandung dalam unit baru. Perhatikan bahwa prototipe gambaran konsisten dengan tipe tplugindeScribe di aplikasi shell, dan menggunakan kata cadangan ekspor tambahan untuk menentukan bahwa proses akan diekspor. Nama proses yang diekspor juga akan muncul di bagian Ekspor Kode Sumber Proyek Utama (tercantum dalam Gambar 4).
unit utama;
antarmuka
PROSEDUR GURNEPLUGIN (VAR DESC: STRING);
ekspor;
Pelaksanaan
PROSEDUR GURNEPLUGIN (VAR DESC: STRING);
Mulai
Desc: = 'Test Plugin v1.00';
akhir;
akhir.
Sebelum menguji plugin ini, salin ke jalur aplikasi utama. Cara termudah adalah dengan membuat plug-in di subdirektori direktori home, dan kemudian mengatur jalur output ke jalur utama (direktori/kondisional dari kotak dialog Opsi Proyek juga dapat digunakan untuk pengaturan ini).
debug
Sekarang izinkan saya memperkenalkan fitur yang lebih baik di Delphi 3: Kemampuan untuk men -debug DLL dari IDE. Dalam proyek DLL, Anda dapat menentukan program sebagai aplikasi host melalui kotak dialog Paramates Run. Kemudian Anda dapat mengatur breakpoint dalam kode DLL Anda dan tekan F9 untuk menjalankannya - seperti yang akan Anda lakukan dalam aplikasi normal. Delphi akan menjalankan program host yang ditentukan dan, dengan menyusun DLL dengan informasi debug, mengarahkan Anda ke breakpoint dalam kode DLL.