Memanggil GetVolumeInformation WinAPI Function from Go To Retrieve Disk Volume Name
Dalam artikel ini, kami akan menangani isu yang dihadapi semasa cuba untuk panggil fungsi GetVolumeInformation daripada Go. Matlamatnya ialah untuk mendapatkan nama volum pemacu yang ditentukan.
Untuk bermula, mari kita fahami masalahnya. Coretan kod adalah berdasarkan spesifikasi fungsi GetVolumeInformation seperti yang ditakrifkan dalam API Windows. Niatnya adalah untuk mendapatkan semula nama volum melalui parameter lpVolumeNameBuffer. Walau bagaimanapun, pelaksanaan kod ini mengakibatkan ralat yang tidak dijangka, menunjukkan kesilapan dalam mengakses memori.
Untuk menyelesaikan isu ini, kita perlu menganalisis aspek kod yang bermasalah. Satu perkara utama ialah jenis tidak selamat.Penunjuk yang digunakan semasa mengisytiharkan pembolehubah untuk lpVolumeNameBuffer dan parameter berkaitan rentetan lain.
Operasi Tidak Selamat dalam Go
Pakej tidak selamat Go menyediakan akses peringkat rendah kepada memori sistem asas, memintas keselamatan jenis untuk melaksanakan operasi baca dan tulis sewenang-wenangnya. Walaupun berkuasa, keupayaan ini disertakan dengan kaveat kemungkinan kerosakan memori jika digunakan secara cuai.
Dalam kes ini, penggunaan tidak selamat.Penunjuk untuk mewakili penimbal rentetan melanggar prinsip keselamatan jenis. Untuk mengelakkan isu sedemikian, kami boleh menggunakan keupayaan pengendalian rentetan Go sendiri.
Penyelesaian
Kod yang diubah suai di bawah mengambil pendekatan yang lebih selamat:
<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>
Dalam versi ini:
Dengan mematuhi amalan keselamatan menaip dan menggunakan pengendalian rentetan Go sendiri, kami boleh mendapatkan semula nama volum dengan berkesan tanpa menghadapi masalah akses memori.
Atas ialah kandungan terperinci Bagaimana untuk Mendapatkan Nama Kelantangan Cakera dengan Selamat Menggunakan Fungsi WinAPI GetVolumeInformation Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!