Ian Lance Taylor writes:
 > On Thu, Aug 29, 2019 at 6:26 PM George Hartzell <hartz...@alerce.com> wrote:
 > [...]
 > There is another approach, which is to use import "C", and then write code 
 > like
 > 
 > const IoctlConstant = C.IoctlConstant
 > type GoIoctlType = C.CIoctlType
 > 
 > and then use those types in code that calls unix.Syscall(SYS_IOCTL,
 > IoctlConstant, &GoIoctlType{value}).

Hi Ian,

Thank you for the followup^2.

After re-reading all of the things that you'd pointed me at, I'd
started heading down that road a bit, but am stuck on one thing and
have a question.

# Where I'm currently stuck

Here's something that compiles and runs:

```
package i2c

// #include <linux/i2c.h>
// #include <linux/i2c-dev.h>
import "C"
import "fmt"

func Foo() {
  im := C.struct_i2c_msg{}
  buf := [2]byte{}

  im.addr = 0x18
  im.flags = C.I2C_M_RD
  im.len = C.__u16(len(buf))
  // im.buf = &buf[0]
  fmt.Println(im)
}
````

The original C structure is defined like so (w/ comments, #defines elided):

```
struct i2c_msg {
  __u16 addr; /* slave address      */
  __u16 flags;
  __u16 len;    /* msg length       */
  __u8 *buf;    /* pointer to msg data      */
};
```

The other approaches that I cribbed supplied the buffer by declaring a
byte slice and taking the address of the first element. If I uncomment
line 15 in the above, I get

```
i2c/i2c.go:15:9: cannot use &buf[0] (type *byte) as type *_Ctype_uchar
in assignment
```

I can't come up with any cast that makes the compiler happy.  I'm also
unsure whether that line runs afoul of this commandment: *Go code may
not store a Go pointer in C memory* from https://golang.org/cmd/cgo/.

Perhaps I should be allocating that memory myself with a call to
`C.malloc` or ???

# The question

If I leave out the buf bit and build it, I end with a dynamically
linked executable, e.g.

```
pi@raspberrypi:~/temper/go/cgo-normal-way $ ldd dummy
        linux-vdso.so.1 (0x7ef23000)
        /usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => 
/usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76f14000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76ed3000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76d85000)
        /lib/ld-linux-armhf.so.3 (0x76f29000)
```

While this is an personal homework problem, I'm also heading towards
building an application and one of the advantages of using Go is the
statically compiled binary.  After your initial comment, I'd thought
perhaps I'd just end up using some cgo magic for the types and structs
but I'd still end up with a static binary.  That doesn't seem to be
the case.

If I go back mimicking the approach used in the x/sys libraries (cgo
-godefs), what particular "private" behavior am I depending on?  Is it
the ability to use `cgo -godefs` to figure out a Go equivalent for the
C data structures, or is it counting on the
``uintptr(unsafe.Pointer(...))` to do the right thing, or something
else?

Thanks again (you've plowed through lots of words...),

g.

-- 
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/23913.47082.559595.453308%40alice.local.

Reply via email to