的EnumPrintersWin32函數(shù)需要和參數(shù)_Out_ LPBYTE pPrinterEnum,一個指向分配的緩沖區(qū)。在 C 中,它是這樣工作的:DWORD cbNeeded, nPrinters;EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, NULL, 0, &cbNeeded, &nPrinters);BYTE *pPrnInfo = malloc(cbNeeded);EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, pPrnInfo, cbNeeded, &cbNeeded, &nPrinters);PRINTER_INFO_5 *pPrinterInfo = (PRINTER_INFO_5 *) pPrnInfo;for (int i=0; i < nPrinters; i++) { printf("pPrinterName: %s\n", pPrinterInfo[i].pPrinterName);}在 Go 中如何使用syscall而不是 cgo完成相同的操作?到目前為止,編譯這么多,但我不知道如何將生成的字節(jié)切片轉(zhuǎn)換為結(jié)構(gòu)數(shù)組(不使用 cgo)。type PrinterInfo5 struct { pPrinterName *uint16 pPortName *uint16 attributes uint32 deviceNotSelectedTimeout uint32 transmissionRetryTimeout uint32}...dll := syscall.MustLoadDLL("winspool.drv")f := dll.MustFindProc("EnumPrintersW")var cbNeeded, nPrinters uint32fmt.Println(cbNeeded, nPrinters)f.Call(PRINTER_ENUM_LOCAL, 0, 5, 0, 0, uintptr(unsafe.Pointer(&cbNeeded)), uintptr(unsafe.Pointer(&nPrinters)))fmt.Println(cbNeeded, nPrinters)var pPrnInfo []byte = make([]byte, cbNeeded)f.Call(PRINTER_ENUM_LOCAL, 0, 5, uintptr(unsafe.Pointer(&pPrnInfo)), uintptr(cbNeeded), uintptr(unsafe.Pointer(&cbNeeded)), uintptr(unsafe.Pointer(&nPrinters)))我試過這個,它成功打印了一次迭代,然后失敗了fatal error: heapBitsBulkBarrier: unaligned arguments:hdr := reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(&pPrnInfo)), Len: int(nPrinters), Cap: int(nPrinters),}s := *(*[]PrinterInfo5)(unsafe.Pointer(&hdr))for _, t := range s { fmt.Println(t)}
1 回答

德瑪西亞99
TA貢獻1770條經(jīng)驗 獲得超3個贊
uintptr(unsafe.Pointer(&pPrnInfo))
上面代碼中的兩個地方都是錯誤的;它為您提供了一個指向切片頭的指針,而不是指向?qū)嶋H支持數(shù)組的指針。你想要這個:
uintptr(unsafe.Pointer(&pPrnInfo[0]))
(由于支持數(shù)組是連續(xù)的,指向支持數(shù)組第一個元素的指針與指向支持數(shù)組本身的指針相同。)
- 1 回答
- 0 關(guān)注
- 190 瀏覽
添加回答
舉報
0/150
提交
取消