Struct types conversion in cgo

474 views
Skip to first unread message

Stephano Zanzin

unread,
Oct 14, 2014, 3:36:26 PM10/14/14
to golan...@googlegroups.com
Hey guys,

Sorry if this is a dumb topic, but I'm not fluent in the cgo implementation yet. First of all, below is the code I'm trying to run:

package main


/*
typedef struct {
  char *name;
} foobar_t;


foobar_t foobar_load(char *name) {
  foobar_t loaded = {name};
  return loaded;
};
*/

import "C"
import "fmt"


type
Foobar C.struct_foobar_t


func setFoobar
(name string) Foobar {
       
return C.foobar_load(C.CString(name))
}


func main
() {
        fmt
.Println(C.GoString(setFoobar("fuuuu").name))
}

When I run this code using go run, I get the following error:

# command-line-arguments
./foobar.go:19: cannot use _Cfunc_foobar_load(_Cfunc_CString(name)) (type C.struct___0) as type Foobar in return argument
./foobar.go:23: setFoobar("fuuuu").name undefined (type Foobar has no field or method name)

I could be wrong, but what I think it's happening is that cgo interprets and informs the compiler that foobar_t is just a simple struct and should be read as C.struct___x by the compiler. This case just happens when I define the struct with typedef then set the function type as it.

If I define the return type of setFoobar() as C.struct___0, voilà:

$ go run foobar.go
fuuuu

But that's not what I need, as I'm creating a go implementation for a really complex and typeful C code.

Any ideas? I'd be very grateful if someone shows up with cool solutions, as I'm working on this for some time now. :-D

Thanks a lot,
Stephano

Emily Maier

unread,
Oct 14, 2014, 4:16:44 PM10/14/14
to golan...@googlegroups.com
> --
> 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...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

I've done some cgo work, and I haven't found any ways of working with
complex struct code that aren't really messy. If all the C code uses the
typedef you could do "type Foobar C.struct__0" in Go.

Emily

Stephano Zanzin

unread,
Oct 14, 2014, 6:46:36 PM10/14/14
to golan...@googlegroups.com
Unfortunately we can't use that way because C.struct___x works in a dynamic fashion to avoid collisions. Anyway, a member of my team just discovered that since version 1.3 a casting of the type and a call of unsafe.Pointer() does the trick. So it would be something like this:

return (*C.struct_foobar_t)(unsafe.Pointer(C.foobar_load(...)))

References:


Thanks for the reply, Emily.

S.
Reply all
Reply to author
Forward
0 new messages