Di bawah platform Windows, Dynamic Link Library (DLL) ialah teknologi komponenisasi yang biasa digunakan Ia membenarkan berbilang atur cara untuk berkongsi perpustakaan fungsi yang sama, mengurangkan pembangunan kod pendua, dan boleh mencapai peningkatan Modul, penggantian dan operasi lain. . Apabila menulis DLL, DllMain adalah fungsi yang paling penting. Artikel ini akan meneroka cara menggunakan Golang untuk melaksanakan fungsi DllMain.
1. Gambaran Keseluruhan DllMain
Pada platform Windows, apabila DLL dimuatkan atau dipunggah, sistem pengendalian akan memanggil fungsi DllMain secara automatik. Prototaip fungsi DllMain adalah seperti berikut:
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved);
Antaranya, parameter hinstDll ialah pemegang contoh DLL itu sendiri, dan parameter fdwReason menunjukkan sebab mengapa DLL dimuatkan, dipunggah atau lain-lain. operasi, dan boleh mengambil nilai berikut:
lpReserved tidak digunakan dan kekal NULL.
Dalam fungsi DllMain, beberapa kerja permulaan dan pembersihan boleh diselesaikan, seperti mendaftar dan menyahdaftar komponen COM, dsb. Di samping itu, perlu diingat bahawa memanggil beberapa fungsi dalam DllMain boleh menyebabkan kebuntuan atau masalah lain Secara amnya tidak disyorkan untuk melakukan terlalu banyak kerja dalam fungsi DllMain, hanya melakukan permulaan dan pembersihan yang diperlukan.
2. Gunakan Golang untuk melaksanakan DllMain
Golang ialah bahasa pengaturcaraan yang pantas dan cekap, dan boleh mengeluarkan perpustakaan pautan dinamik bahasa C, jadi anda boleh menggunakan Golang untuk melaksanakan fungsi DllMain.
Pertama, kami perlu memberitahu Golang untuk mengeluarkan perpustakaan pautan dinamik Anda boleh menggunakan arahan berikut:
go build -buildmode=c-shared -o example.dll example.go
Antaranya, example.go ialah fail kod Golang yang kami tulis, dan example.dll ialah fail perpustakaan pautan dinamik output.
Seterusnya, kita perlu melaksanakan fungsi DllMain dalam kod Golang. Memandangkan Golang ialah bahasa statik dan tidak menyokong operasi penunjuk dan penunjuk mentah dalam bahasa C, anda perlu menggunakan penterjemah bahasa C untuk memanggil fungsi Golang melalui kod bahasa C. Secara khusus, kami boleh menyambungkan kod bahasa C dan kod Golang melalui arahan #cgo. Berikut ialah contoh:
package main import "C" var ( hInstance C.HMODULE ) //export DllMain func DllMain(hinstDLL C.HMODULE, fdwReason C.DWORD, lpvReserved C.LPVOID) C.BOOL { switch fdwReason { case C.DLL_PROCESS_ATTACH: hInstance = hinstDLL // do initialize job here case C.DLL_PROCESS_DETACH: // do cleanup job here case C.DLL_THREAD_ATTACH: // do something when a new thread created case C.DLL_THREAD_DETACH: // do something when a thread was ended } return 1 }
Dalam contoh ini, kami mentakrifkan hInstance pembolehubah luaran dan menetapkan pemegang DLL kepadanya dalam fungsi DllMain. Kami boleh melengkapkan kerja permulaan dan pembersihan dalam fungsi DllMain, dan menambah logik pemprosesan lain seperti yang diperlukan. Ambil perhatian bahawa disebabkan mekanisme pengurusan ingatan Golang, jika anda perlu menggunakan objek Golang dalam DllMain, anda perlu memastikan bahawa kitaran hayatnya tidak melebihi skop fungsi DllMain.
3. Susun dan uji
Selepas menulis kod Golang, kita perlu menyusunnya dan mengujinya. Pada platform Windows, kita boleh menggunakan gesaan arahan "Visual Studio Native Tools Command Prompt" terbina dalam, masukkan tetingkap cmd di bawah direktori projek, dan jalankan arahan berikut:
set CGO_ENABLED=1 set CGO_CFLAGS=-Wall go build -buildmode=c-shared -o example.dll example.go
Antaranya , CGO_ENABLED bermakna Anda boleh menggunakan penterjemah bahasa C, CGO_CFLAGS menunjukkan pilihan kompilasi dan -Wall menunjukkan menghidupkan semua amaran. Perintah go build menyusun kod Golang ke dalam fail DLL.
Selepas penyusunan selesai, kami boleh menggunakan Visual Studio untuk mencipta aplikasi konsol, dan kemudian memuatkan dan memunggah perpustakaan pautan dinamik dengan memanggil fungsi LoadLibrary dan UnloadLibrary untuk menguji sama ada fungsi DllMain dipanggil. Untuk contoh ujian khusus, sila rujuk kod berikut:
#include <windows.h> #include <stdio.h> typedef BOOL(WINAPI* DllMainFunc)(HINSTANCE, DWORD, LPVOID); int main() { HMODULE hDll = LoadLibrary("example.dll"); if (hDll == NULL) { printf("Load library failed.\n"); } else { printf("Load library succeed.\n"); DllMainFunc pDllMain = (DllMainFunc)GetProcAddress(hDll, "DllMain"); if (pDllMain == NULL) { printf("Get function address failed.\n"); } else { printf("Get function address succeed.\n"); (*pDllMain)(hDll, DLL_PROCESS_ATTACH, NULL); (*pDllMain)(hDll, DLL_PROCESS_DETACH, NULL); } FreeLibrary(hDll); } return 0; }
Selepas menjalankan program ujian, kita boleh melihat output konsol "Muat perpustakaan berjaya dan "Dapatkan alamat fungsi berjaya.", menunjukkan pemuatan dan mencari alamat fungsi berfungsi dengan baik dan tiada ralat berlaku semasa memanggil fungsi DllMain.
4. Ringkasan
Artikel ini memperkenalkan secara ringkas konsep dan tujuan fungsi DllMain, dan kemudian mengambil Golang sebagai contoh untuk menerangkan cara menggunakan Golang untuk melaksanakan fungsi DllMain. Walaupun Golang adalah bahasa pengaturcaraan yang cekap, ia tidak sesuai untuk semua senario Anda perlu memilih susunan bahasa dan teknologi yang sesuai selepas menimbang kebaikan dan keburukan.
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan fungsi DllMain menggunakan Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!