Go's unsafe.Sizeof
возвращает результат, отличный от C * sizeof
.
main.go:
package main
import (
"unsafe"
)
type gpioeventdata struct {
Timestamp uint64
ID uint32
}
func main() {
eventdata := gpioeventdata{}
println("Size", unsafe.Sizeof(eventdata))
}
Печатает 12
при компиляции с env GOOS=linux GOARCH=arm GOARM=6 go build
в macOS и работает на Raspberry Pi Zero.
gpio.c:
#include <stdio.h>
#include <linux/gpio.h>
int main() {
printf("sizeof gpioevent_data %zu\n", sizeof(struct gpioevent_data));
}
Печатает 16
при компиляции и запуске на Raspberry (с gcc
).
определение структуры в gpio.h:
struct gpioevent_data {
__u64 timestamp;
__u32 id;
};
Редактировать
Я уже думал, что это из-за выравнивания, но многие люди передают структуры Go на syscall.Syscall
(например, https://github.com/stapelberg/hmgo/blob/master/internal/gpio/reset.go#L49). Так что это в принципе неправильно, и вы никогда не должны этого делать?
Если это не так, то каков правильный подход - вызывать системные вызовы с помощью go, чтобы правильно работать с различными архитектурами. Например, вызовы GPIO ioctl:
ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
...
struct gpioevent_data event;
ret = read(req.fd, &event, sizeof(event));