-
Notifications
You must be signed in to change notification settings - Fork 88
Description
Alluded to here:
I'm not 100% sure about this, and it's more to pick @alexbrainman brain as I think you'll have better insight into this than me.
Functions such as https://docs.microsoft.com/en-us/windows/win32/printdocs/getprinter take a single chunk of memory to return an array of (for level 5, for example) PRINTER_INFO_5 structures. This are correctly represented as such:
type PRINTER_INFO_5 struct {
PrinterName *uint16
PortName *uint16
Attributes uint32
DeviceNotSelectedTimeout uint32
TransmissionRetryTimeout uint32
}
The way this works with the string pointers is that space is allocated for N PRINTER_INFO_5 structs + an additional amount of space at the bottom for the strings. The string pointers within the structs then point at the correct offset into that additional space.
This can be seen below (I added some debug):
buf extent C00007C000 -> C00007C558
p.PrinterName for printer 0 @ C00007C504
p.PrinterName for printer 1 @ C00007C4C8
p.PrinterName for printer 2 @ C00007C48C
p.PrinterName for printer 3 @ C00007C406
p.PrinterName for printer 4 @ C00007C3C0
p.PrinterName for printer 5 @ C00007C29A
p.PrinterName for printer 6 @ C00007C254
p.PrinterName for printer 7 @ C00007C20E
p.PrinterName for printer 8 @ C00007C1EE
p.PrinterName for printer 9 @ C00007C192
My concern is, (and I believe I'm correct here, but may not be so would love your input) the go runtime is free to move the address of the buf allocation? However the string pointers "within" the buf allocation would not change the address they are pointing at, so would no longer point to the correct place? As I understand it, that is why the cGo rules do not allow you to pass a pointer to a Go struct containing Go pointers into cGo? - this in effect is circumventing that with a byte buffer but since it's cast it's the same thing
If this is a problem how can it be addressed? I presume using an allocater like LocalAlloc would do the trick ensuring the memory is not in view of the Go runtime. Though I can't see anywhere in the standard library or x/sys/windows which exposes this. C.malloc a possibility, though that introduces an (undesirable?) CGo dependency.