Go での Get VolumeInformation WinAPI 関数の呼び出し
この記事では、Go から Get VolumeInformation WinAPI 関数を使用してボリュームの名前を取得する試みについて詳しく説明します。ただし、最初の作業で予期しないエラーが発生しました。
問題ステートメント
この問題は、文字列バッファを lpVolumeNameBuffer パラメータとして渡そうとしたときに発生しました。コードは、「予期しない障害アドレス 0xffffffffffffffff」というエラーで失敗しました。
分析
Go 文字列を uint16 配列へのポインターに変換するための unsafe.Pointer の使用がエラーの原因として特定されました。 Go では、一般に、結果をよく理解せずにポインタを直接操作しないでください。
解決策
この問題を解決するために、コードが書き直されて修正コードが作成されました。 -size バッファを 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 中国語 Web サイトの他の関連記事を参照してください。