Go's unsafe.Sizeof
is returning a different result than C's sizeof
.
main.go:
package main
import (
"unsafe"
)
type gpioeventdata struct {
Timestamp uint64
ID uint32
}
func main() {
eventdata := gpioeventdata{}
println("Size", unsafe.Sizeof(eventdata))
}
Prints 12
when compiled with env GOOS=linux GOARCH=arm GOARM=6 go build
on macOS and run on Raspberry Pi Zero.
gpio.c:
#include <stdio.h>
#include <linux/gpio.h>
int main() {
printf("sizeof gpioevent_data %zu\n", sizeof(struct gpioevent_data));
}
Prints 16
when compiled and run on Raspberry (with gcc
).
struct definition in gpio.h:
struct gpioevent_data {
__u64 timestamp;
__u32 id;
};
Edit
I already thought that this is due to alignment, but a lot of people are passing Go structs to syscall.Syscall
(e.g. https://github.com/stapelberg/hmgo/blob/master/internal/gpio/reset.go#L49). So that's basically wrong and you should never do that?
If that's wrong, what would be the correct approach calling syscalls with go so that works correctly with different architectures. For example GPIO ioctl calls:
ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
...
struct gpioevent_data event;
ret = read(req.fd, &event, sizeof(event));