Go To Retrieve Disk Volume Name から Get VolumeInformation WinAPI 関数を呼び出す
この記事では、 Go から GetVolumeInformation 関数を呼び出します。目標は、指定されたドライブのボリューム名を取得することです。
まず、問題を理解しましょう。このコード スニペットは、Windows API で定義されている GetVolumeInformation 関数の仕様に基づいています。その目的は、lpVolumeNameBuffer パラメーターを通じてボリューム名を取得することでした。ただし、このコードを実行すると、メモリへのアクセス障害を示す予期しないエラーが発生しました。
この問題を解決するには、コードの問題のある側面を分析する必要があります。重要なポイントの 1 つは、lpVolumeNameBuffer およびその他の文字列関連パラメーターの変数を宣言するときに使用される unsafe.Pointer 型です。
Go の安全でない操作
Go の unsafe パッケージは次のことを提供します。基礎となるシステム メモリへの低レベル アクセス。任意の読み取りおよび書き込み操作を実行するためにタイプ セーフティをバイパスします。この機能は強力ですが、不注意に使用するとメモリ破損の可能性があるという注意事項があります。
この場合、文字列バッファを表すために unsafe.Pointer を使用すると、型安全性の原則に違反します。このような問題を回避するには、Go 独自の文字列処理機能を利用できます。
解決策
以下の変更されたコードは、より安全なアプローチを採用しています。
<code class="go">package main import ( "fmt" "syscall" ) func main() { var 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, _ := syscall.LoadLibrary("kernel32.dll") getVolume, _ := syscall.GetProcAddress(kernel32, "GetVolumeInformationW") 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) fmt.Println(ret, callErr, syscall.UTF16ToString(VolumeNameBuffer)) }</code>
このバージョンでは:
タイプ セーフティの実践を遵守し、Go 独自の文字列処理を利用することにより、メモリ アクセスの問題が発生することなくボリューム名を効果的に取得できます。
以上がGo の WinAPI GetVolumeInformation 関数を使用してディスク ボリューム名を安全に取得する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。