Heim > Backend-Entwicklung > Golang > Wie rufe ich die WinAPI-Funktion GetVolumeInformation in Go korrekt auf und vermeide unerwartete Fehler?

Wie rufe ich die WinAPI-Funktion GetVolumeInformation in Go korrekt auf und vermeide unerwartete Fehler?

Susan Sarandon
Freigeben: 2024-10-25 08:17:28
Original
484 Leute haben es durchsucht

How to correctly invoke the GetVolumeInformation WinAPI function in Go, and avoid unexpected errors?

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>
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage