Maison  >  Article  >  développement back-end  >  Comment implémenter la fonction DllMain à l'aide de Golang

Comment implémenter la fonction DllMain à l'aide de Golang

PHPz
PHPzoriginal
2023-04-06 09:11:231090parcourir

Sous la plate-forme Windows, la bibliothèque de liens dynamiques (DLL) est une technologie de composantisation couramment utilisée. Elle permet à plusieurs programmes de partager la même bibliothèque de fonctions, réduisant ainsi le développement de codes en double et permettant les mises à niveau de modules, le remplacement et d'autres opérations. Lors de l'écriture d'une DLL, DllMain est la fonction la plus importante. Cet article explique comment utiliser Golang pour implémenter la fonction DllMain.

1. Présentation de DllMain

Sur la plateforme Windows, lorsque la DLL est chargée ou déchargée, le système d'exploitation appellera automatiquement la fonction DllMain. Le prototype de la fonction DllMain est le suivant :

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpReserved);

Parmi eux, le paramètre hinstDll est le handle d'instance de la DLL elle-même, et le paramètre fdwReason indique la raison pour laquelle la DLL est chargée, déchargée ou d'autres opérations qu'elle peut effectuer. les valeurs suivantes :

  • DLL_PROCESS_ATTACH : Lorsque la DLL est chargée Appelée
  • DLL_PROCESS_DETACH : appelée lorsque la DLL est déchargée
  • DLL_THREAD_ATTACH : appelée lorsque le thread est créé
  • DLL_THREAD_DETACH : appelée lorsque le thread se termine

lpReserved n'est pas utilisé et reste NULL.

Dans la fonction DllMain, certains travaux d'initialisation et de nettoyage peuvent être effectués, tels que l'enregistrement et la désinscription de composants COM, etc. De plus, il convient de noter que l'appel de certaines fonctions dans DllMain peut provoquer un blocage ou d'autres problèmes. Il n'est généralement pas recommandé de faire trop de travail dans la fonction DllMain, effectuez uniquement l'initialisation et le nettoyage nécessaires.

2. Utilisez Golang pour implémenter DllMain

Golang est un langage de programmation rapide et efficace, et peut générer une bibliothèque de liens dynamiques en langage C, vous pouvez donc utiliser Golang pour implémenter la fonction DllMain.

Tout d'abord, nous devons dire à Golang de générer la bibliothèque de liens dynamiques. Vous pouvez utiliser la commande suivante :

go build -buildmode=c-shared -o example.dll example.go

Parmi eux, example.go est le fichier de code Golang que nous avons écrit, et example.dll est la bibliothèque de liens dynamiques de sortie. déposer.

Ensuite, nous devons implémenter la fonction DllMain dans le code Golang. Étant donné que Golang est un langage statique et ne prend pas en charge les opérations de pointeur ni les pointeurs bruts en langage C, vous devez utiliser un interpréteur de langage C pour appeler les fonctions Golang via le code du langage C. Plus précisément, nous pouvons connecter le code du langage C et le code Golang via la directive #cgo. Voici un exemple :

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
}

Dans cet exemple, nous définissons une variable externe hInstance et lui attribuons le handle de la DLL dans la fonction DllMain. Nous pouvons terminer le travail d'initialisation et de nettoyage dans la fonction DllMain et ajouter une autre logique de traitement si nécessaire. Notez qu'en raison du mécanisme de gestion de la mémoire de Golang, si vous devez utiliser des objets Golang dans DllMain, vous devez vous assurer que leur cycle de vie ne dépasse pas la portée de la fonction DllMain.

3. Compiler et tester

Après avoir écrit le code Golang, nous devons le compiler et le tester. Sur la plate-forme Windows, nous pouvons utiliser l'invite de commande intégrée « Visual Studio Native Tools Command Prompt » dans Visual Studio, entrer dans la fenêtre cmd dans le répertoire du projet et exécuter la commande suivante :

set CGO_ENABLED=1
set CGO_CFLAGS=-Wall
go build -buildmode=c-shared -o example.dll example.go

Parmi elles, CGO_ENABLED signifie que l'interpréteur du langage C peut être utilisé, CGO_CFLAGS indique les options de compilation, -Wall indique l'activation de tous les avertissements. La commande go build compile le code Golang dans un fichier DLL.

Une fois la compilation terminée, nous pouvons utiliser Visual Studio pour créer une application console, puis charger et décharger la bibliothèque de liens dynamiques en appelant les fonctions LoadLibrary et UnloadLibrary pour tester si la fonction DllMain est appelée. Pour des exemples de tests spécifiques, veuillez vous référer au code suivant :

#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;
}

Après avoir exécuté le programme de test, nous pouvons voir la sortie de la console "Charger la bibliothèque avec succès." et "Obtenir l'adresse de la fonction avec succès.", indiquant que le chargement et la recherche des adresses de fonction fonctionnent. normalement, et en appelant Aucune erreur ne s'est produite pendant la fonction DllMain.

4. Résumé

Cet article présente brièvement le concept et le but de la fonction DllMain, puis prend Golang comme exemple pour décrire comment utiliser Golang pour implémenter la fonction DllMain. Bien que Golang soit un langage de programmation efficace, il ne convient pas à tous les scénarios. Vous devez choisir le langage et la pile technologique appropriés après avoir pesé le pour et le contre.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn