Aufrufen der GetVolumeInformation WinAPI-Funktion in Go
Dieser Artikel beschreibt einen Versuch, den Namen eines Volumes mithilfe der GetVolumeInformation WinAPI-Funktion von Go abzurufen. Bei den ersten Versuchen ist jedoch ein unerwarteter Fehler aufgetreten.
Problembeschreibung
Das Problem trat auf, als versucht wurde, einen Zeichenfolgenpuffer als lpVolumeNameBuffer-Parameter zu übergeben. Der Code ist mit dem Fehler „unerwartete Fehleradresse 0xffffffffffffffff“ fehlgeschlagen.
Analyse
Die Verwendung von unsafe.Pointer zum Konvertieren der Go-Zeichenfolge in einen Zeiger auf ein uint16-Array wurde als Fehlerursache identifiziert. In Go sollten Zeiger im Allgemeinen nicht direkt manipuliert werden, ohne die Konsequenzen gut zu verstehen.
Lösung
Um dieses Problem zu beheben, wurde der Code neu geschrieben, um eine Lösung zu erstellen -size Puffer mit uint16 Zeichen und übergeben Sie einen Zeiger auf das erste Element des Puffers als Parameter lpVolumeNameBuffer. Dieser Ansatz stellt sicher, dass der Puffer richtig ausgerichtet ist und vermeidet die Notwendigkeit, unsafe.Pointer zu verwenden.
Hier ist der korrigierte Code:
<code class="go">package main import ( "fmt" "syscall" ) func main() { const RootPathName = `C:\` var VolumeNameBuffer = make([]uint16, syscall.MAX_PATH+1) var nVolumeNameSize = uint32(len(VolumeNameBuffer)) var VolumeSerialNumber uint32 var MaximumComponentLength uint32 var FileSystemFlags uint32 var FileSystemNameBuffer = make([]uint16, 255) var nFileSystemNameSize uint32 = syscall.MAX_PATH + 1 kernel32, err := syscall.LoadLibrary("kernel32.dll") if err != nil { fmt.Println("Error loading kernel32: ", err) return } getVolume, err := syscall.GetProcAddress(kernel32, "GetVolumeInformationW") if err != nil { fmt.Println("Error getting GetVolumeInformation address: ", err) return } var nargs uintptr = 8 ret, _, callErr := syscall.Syscall9(uintptr(getVolume), nargs, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(RootPathName))), uintptr(unsafe.Pointer(&VolumeNameBuffer[0])), uintptr(nVolumeNameSize), uintptr(unsafe.Pointer(&VolumeSerialNumber)), uintptr(unsafe.Pointer(&MaximumComponentLength)), uintptr(unsafe.Pointer(&FileSystemFlags)), uintptr(unsafe.Pointer(&FileSystemNameBuffer[0])), uintptr(nFileSystemNameSize), 0) if ret != 0 { fmt.Println("Call succeeded: ", syscall.UTF16ToString(VolumeNameBuffer)) } else { fmt.Println("Call failed: ", callErr) } }</code>
Dieser geänderte Code sollte den Namen erfolgreich abrufen und ausgeben des angegebenen Volumens.
Das obige ist der detaillierte Inhalt vonWie rufe ich die WinAPI-Funktion GetVolumeInformation in Go korrekt auf und vermeide unerwartete Fehler?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!