>  기사  >  백엔드 개발  >  Go에서 GetVolumeInformation WinAPI 함수를 올바르게 호출하고 예기치 않은 오류를 방지하는 방법은 무엇입니까?

Go에서 GetVolumeInformation WinAPI 함수를 올바르게 호출하고 예기치 않은 오류를 방지하는 방법은 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-10-25 08:17:28386검색

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

Go에서 GetVolumeInformation WinAPI 함수 호출

이 문서에서는 Go에서 GetVolumeInformation WinAPI 함수를 사용하여 볼륨 이름을 검색하려는 시도에 대해 자세히 설명합니다. 그러나 초기 작업에서 예상치 못한 오류가 발생했습니다.

문제 설명

문자열 버퍼를 lpVolumeNameBuffer 매개변수로 전달하려고 할 때 문제가 발생했습니다. "예기치 않은 오류 주소 0xffffffffffffffff" 오류로 인해 코드가 실패했습니다.

분석

unsafe.Pointer를 사용하여 Go 문자열을 uint16 배열에 대한 포인터로 변환 오류의 원인으로 확인되었습니다. Go에서는 일반적으로 결과에 대한 충분한 이해 없이 포인터를 직접 조작해서는 안 됩니다.

해결책

이 문제를 해결하기 위해 코드를 다시 작성하여 고정된 포인터를 생성했습니다. - uint16자의 버퍼 크기를 지정하고 버퍼의 첫 번째 요소에 대한 포인터를 lpVolumeNameBuffer 매개변수로 전달합니다. 이 접근 방식을 사용하면 버퍼가 올바르게 정렬되고 unsafe.Pointer를 사용할 필요가 없습니다.

수정된 코드는 다음과 같습니다.

<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>

이 수정된 코드는 이름을 성공적으로 검색하고 인쇄해야 합니다. 지정된 볼륨의

위 내용은 Go에서 GetVolumeInformation WinAPI 함수를 올바르게 호출하고 예기치 않은 오류를 방지하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.