Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk melaksanakan fungsi DllMain menggunakan Golang

Bagaimana untuk melaksanakan fungsi DllMain menggunakan Golang

PHPz
PHPzasal
2023-04-06 09:11:231106semak imbas

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:

  • DLL_PROCESS_ATTACH: dipanggil apabila DLL dimuatkan
  • DLL_PROCESS_DETACH: dipanggil apabila DLL dipunggah
  • DLL_THREAD_ATTACH: dipanggil apabila DLL_ATTACH benang dicipta
  • DLL_THREAD_DETACH: dipanggil apabila benang tamat

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn