Problème :
Lors de la tentative d'appel de la fonction GetVolumeInformation depuis l'intérieur un programme Go, une erreur se produit en raison d'une opération de pointeur non sécurisée.
Contexte :
La fonction GetVolumeInformation récupère des informations sur un volume spécifié, y compris son nom. Il nécessite plusieurs paramètres d'entrée et de sortie pour fonctionner.
Solution :
Pour résoudre l'erreur, il est crucial de comprendre le but et l'utilisation du package non sécurisé dans Go. Le package unsafe permet la manipulation directe des adresses mémoire, en contournant la sécurité de type du langage. Cependant, il doit être utilisé avec prudence.
L'une des opérations disponibles pour le package non sécurisé consiste à convertir un pointeur vers un type spécifique en un pointeur, qui représente un pointeur vers un type arbitraire. Cette flexibilité permet de lire et d'écrire des emplacements de mémoire arbitraires.
Dans le code fourni, l'erreur est survenue car le VolumeNameBuffer a été transmis à la fonction GetVolumeInformation à l'aide d'unsafe.Pointer(&lpVolumeNameBuffer). Ce cast tente de convertir la variable chaîne en pointeur.
Code révisé :
Pour résoudre le problème, le code peut utiliser un tableau de uint16 (la taille de qui est déterminé par syscall.MAX_PATH) pour recevoir le nom du volume et le transmettre comme argument à la fonction GetVolumeInformation. Cette approche évite d'avoir à utiliser Pointer et garantit la sécurité du type.
<code class="go">import ( "fmt" "syscall" "unsafe" ) func main() { var RootPathName = `C:\` var VolumeNameBuffer = make([]uint16, syscall.MAX_PATH+1) var nVolumeNameSize = uint32(len(VolumeNameBuffer)) // Other parameters... kernel32, _ := syscall.LoadLibrary("kernel32.dll") getVolume, _ := syscall.GetProcAddress(kernel32, "GetVolumeInformationW") var nargs uintptr = 8 ret, _, callErr := syscall.Syscall9(uintptr(getVolume), nargs, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(RootPathName))), uintptr(unsafe.Pointer(&VolumeNameBuffer[0])), uintptr(nVolumeNameSize), // Other parameters... 0) fmt.Println(ret, callErr, syscall.UTF16ToString(VolumeNameBuffer)) }</code>
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!