Quick summary, I'm trying to understand the Go structures that cgo gives me, how they map back onto the C structures and why a Go struct that doesn't quite match the cgo output seems to work anyway.
I've called out two explicit questions down below. --- The Linux kernel provides a character device interface to I2C devices, and the [i2c-tools] package provides a C library with "convenient" access functions. I'm working on a Go library for the kernel interface on a Raspberry Pi, because I need it for a project *and* as an etude [so please, don't do too much of my "homework" for me...;)] While digging around for prior art, I found a [partial implementation by tetsu-koba][tetsu-koba]. Starting from that, I have working bits to talk to devices via the I2C versions of the commands. My next step was to implement the [i2c-tools] SMBus functions. That requires Go versions of the two C structures that they use. A bit of research into creating the mapping led to using `cgo -godefs`. Along the way, I stumbled on a [partial implementation of the SMBus bits][brandonagr-smbus] by brandon...@gmail.com. I ended up with this cgo input file: ```go package main /* #include <stdio.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> */ import "C" type I2CMsg C.struct_i2c_msg const Sizeof_I2CMsg = C.sizeof_struct_i2c_msg type I2CSMBusIoctlData C.struct_i2c_smbus_ioctl_data const Sizeof_I2CSMBusIoctlData = C.sizeof_struct_i2c_smbus_ioctl_data type Blort C.struct_blort type I2CSMBusData C.union_i2c_smbus_data const Sizeof_I2CSMBusData = C.sizeof_union_i2c_smbus_data ``` It generates this output: ```go // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs foo.go package main type I2CMsg struct { Addr uint16 Flags uint16 Len uint16 Buf *uint8 } const Sizeof_I2CMsg = 0xc type I2CSMBusIoctlData struct { Write uint8 Command uint8 Size uint32 Data *[34]byte } const Sizeof_I2CSMBusIoctlData = 0xc type Blort struct{} type I2CSMBusData [34]byte const Sizeof_I2CSMBusData = 0x22 ``` @brandonagr ended up with something that's different for his version of the i2c_smbus_ioctl_data struct: ```go type i2c_smbus_ioctl_data struct { read_write uint8 command uint8 size int data *uint8 } ``` but I can see how it's the same "shape". ## Question #1 On the *other hand, @tetsu-koba's version of the i2c_msg struct: ```go type i2c_msg struct { addr uint16 flags uint16 len uint16 __padding uint16 buf uintptr } ``` seems to be fundamentally different from the `cgo -godefs` version: ```go type I2CMsg struct { Addr uint16 Flags uint16 Len uint16 Buf *uint8 } ``` Before I figured out how to use `cgo -godefs`, I rationalized @tetsu-koba's struct with the explanation that the `buf` pointer was being padded out to a 32-bit boundary and was comforted by the fact that it seems to work (I can use it to talk to e.g. an MCP9808 temperature sensor). But, the `cgo -godefs` output seems to be a different shape, I don't see how the Buf field ends up in the right place. I haven't tried *using* it yet, I'd like to understand the why before I comfort myself with a "seems to work, onward...". Left to my own devices I thought about trying to get at the assembly language output for the various structs and seeing what was going on, but that seemed to be One Yak Too Far. Can anyone explain [or a big big clue] what's going on? Is one right and the other wrong? Are both somehow correct? ## Question #2 While I'm on this topic, I notice that `cgo -godefs` converted the struct/field names to Go camel case versions (and stripped the "read_" prefix from one). But, both @tetsu-koba and @brandonagr stuck with the C struct names. I've noticed that various go libaries that refer to kernel data structures (e.g. constants/#defines) don't rename them in Go style. What is the accepted practice in this situation? Thanks! g. [brandonagr-smbus]: https://groups.google.com/d/msg/golang-nuts/zHyqv36oFVI/Jzx1ztCZbHwJ [i2c-tools]: https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/ [tetsu-koba]: https://gist.github.com/tetsu-koba/33b339d26ac9c730fb09773acf39eac5 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/23912.27259.564057.295915%40alice.local.