的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 uint32
fmt.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)
}
德玛西亚99
相关分类