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.

Reply via email to