Bagaimana untuk menggunakan fungsi GetVolumeInformation WinAPI dengan betul dalam Go dan mengelakkan ralat yang tidak dijangka?

Susan Sarandon
Lepaskan: 2024-10-25 08:17:28
asal
397 orang telah melayarinya

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

Memanggil GetVolumeInformation WinAPI Function dalam Go

Artikel ini memperincikan percubaan untuk mendapatkan semula nama volum menggunakan fungsi GetVolumeInformation WinAPI daripada Go. Walau bagaimanapun, usaha awal mengalami ralat yang tidak dijangka.

Pernyataan Masalah

Isu timbul apabila cuba menghantar penimbal rentetan sebagai parameter lpVolumeNameBuffer. Kod itu gagal dengan ralat "alamat kesalahan tidak dijangka 0xffffffffffffffff."

Analisis

Penggunaan tidak selamat.Penunjuk untuk menukar rentetan Go kepada penuding kepada tatasusunan uint16 dikenal pasti sebagai punca kesilapan. Dalam Go, penunjuk pada umumnya tidak boleh dimanipulasi secara langsung tanpa pemahaman yang baik tentang akibatnya.

Penyelesaian

Untuk menyelesaikan isu ini, kod telah ditulis semula untuk mencipta tetapan -saiz penimbal uint16 aksara dan hantar penuding kepada elemen pertama penimbal sebagai parameter lpVolumeNameBuffer. Pendekatan ini memastikan bahawa penimbal dijajarkan dengan betul dan mengelakkan keperluan untuk menggunakan yang tidak selamat.Penunjuk.

Berikut ialah kod yang diperbetulkan:

<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>
Salin selepas log masuk

Kod yang diubah suai ini seharusnya berjaya mendapatkan dan mencetak nama daripada volum yang ditentukan.

Atas ialah kandungan terperinci Bagaimana untuk menggunakan fungsi GetVolumeInformation WinAPI dengan betul dalam Go dan mengelakkan ralat yang tidak dijangka?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!