的EnumPrintersWin32函数需要和参数_Out_ LPBYTE pPrinterEnum,一个指向分配的缓冲区。在 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完成相同的操作?到目前为止,编译这么多,但我不知道如何将生成的字节切片转换为结构数组(不使用 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条经验 获得超3个赞
uintptr(unsafe.Pointer(&pPrnInfo))
上面代码中的两个地方都是错误的;它为您提供了一个指向切片头的指针,而不是指向实际支持数组的指针。你想要这个:
uintptr(unsafe.Pointer(&pPrnInfo[0]))
(由于支持数组是连续的,指向支持数组第一个元素的指针与指向支持数组本身的指针相同。)
- 1 回答
- 0 关注
- 150 浏览
添加回答
举报
0/150
提交
取消