diff --git a/_examples/hi/hi.go b/_examples/hi/hi.go index bec8f68..b3a35d0 100644 --- a/_examples/hi/hi.go +++ b/_examples/hi/hi.go @@ -15,8 +15,10 @@ const ( ) var ( - Debug = false // Debug switches between debug and prod - Anon = Person{Age: 1, Name: ""} // Anon is a default anonymous person + Debug = false // Debug switches between debug and prod + Anon = Person{Age: 1, Name: ""} // Anon is a default anonymous person + IntSlice = []int{1, 2} // A slice of ints + IntArray = [2]int{1, 2} // An array of ints ) // Hi prints hi from Go diff --git a/bind/gencpy.go b/bind/gencpy.go index 9ab9510..ff8c90f 100644 --- a/bind/gencpy.go +++ b/bind/gencpy.go @@ -850,6 +850,14 @@ func (g *cpyGen) genConst(o Const) { } func (g *cpyGen) genVar(v Var) { + + ret := qualifiedType(v.GoType()) + switch v.GoType().(type) { + case *types.Array, *types.Slice: + g.decl.Printf("/* wrapping %s */\n", v.GoType().String()) + g.decl.Printf("typedef void* %s;\n\n", ret) + } + id := g.pkg.Name() + "_" + v.Name() doc := v.doc { diff --git a/bind/gengo.go b/bind/gengo.go index ef7cf37..96578ee 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -276,7 +276,7 @@ func (g *goGen) genStruct(s Struct) { } ft := f.Type() - ftname := g.qualifiedType(ft) + ftname := qualifiedType(ft) if needWrapType(ft) { ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", s.ID(), i+1) g.Printf("//export %s\n", ftname) @@ -431,8 +431,15 @@ func (g *goGen) genConst(o Const) { func (g *goGen) genVar(o Var) { pkgname := o.pkg.Name() + ret := qualifiedType(o.GoType()) + + switch o.GoType().(type) { + case *types.Array, *types.Slice: + g.Printf("//export %s\n", ret) + g.Printf("type %s unsafe.Pointer\n\n", ret) + } + g.Printf("//export GoPy_get_%s\n", o.id) - ret := g.qualifiedType(o.GoType()) g.Printf("func GoPy_get_%[1]s() %[2]s {\n", o.id, ret) g.Indent() if o.needWrap() { @@ -485,30 +492,8 @@ func (g *goGen) tupleString(tuple []*Var) string { for _, v := range tuple { n := v.Name() typ := v.GoType() - str = append(str, n+" "+g.qualifiedType(typ)) + str = append(str, n+" "+qualifiedType(typ)) } return strings.Join(str, ", ") } - -func (g *goGen) qualifiedType(typ types.Type) string { - switch typ := typ.(type) { - case *types.Basic: - return typ.Name() - case *types.Named: - obj := typ.Obj() - switch typ.Underlying().(type) { - case *types.Struct: - return "GoPy_" + obj.Pkg().Name() + "_" + obj.Name() - case *types.Interface: - if obj.Name() == "error" { - return "error" - } - return "GoPy_" + obj.Name() - default: - return "GoPy_ooops_" + obj.Name() - } - } - - return fmt.Sprintf("%#T", typ) -} diff --git a/bind/types.go b/bind/types.go index d8c8253..6ef44e6 100644 --- a/bind/types.go +++ b/bind/types.go @@ -31,6 +31,12 @@ func needWrapType(typ types.Type) bool { case *types.Struct: return true } + case *types.Array: + return true + case *types.Slice: + return true + case *types.Interface: + return true } return false } diff --git a/bind/vars.go b/bind/vars.go index 4de0e6f..21fb144 100644 --- a/bind/vars.go +++ b/bind/vars.go @@ -46,6 +46,10 @@ func newVarFrom(p *Package, v *types.Var) *Var { return newVar(p, v.Type(), v.Name(), v.Name(), p.getDoc("", v)) } +func getTypeString(t types.Type) string { + return types.TypeString(t, func(*types.Package) string { return " " }) +} + func getTypedesc(t types.Type) typedesc { switch typ := t.(type) { case *types.Basic: @@ -82,6 +86,16 @@ func getTypedesc(t types.Type) typedesc { default: panic(fmt.Errorf("unhandled type: %#v", typ)) } + case *types.Array: + id := fmt.Sprintf("_array_%d_%s", typ.Len(), getTypeString(typ.Elem())) + return typedesc{ + ctype: "GoPy_" + id, + cgotype: "GoPy_" + id, + pyfmt: "O&", + c2py: "cgopy_cnv_c2py_" + id, + py2c: "cgopy_cnv_py2c_" + id, + } + case *types.Pointer: elem := typ.Elem() return getTypedesc(elem) @@ -184,3 +198,33 @@ func (v *Var) needWrap() bool { typ := v.GoType() return needWrapType(typ) } + +func qualifiedType(typ types.Type) string { + switch typ := typ.(type) { + case *types.Basic: + return typ.Name() + case *types.Named: + obj := typ.Obj() + switch typ.Underlying().(type) { + case *types.Struct: + return "GoPy_" + obj.Pkg().Name() + "_" + obj.Name() + case *types.Interface: + if obj.Name() == "error" { + return "error" + } + return "GoPy_" + obj.Name() + default: + return "GoPy_ooops_" + obj.Name() + } + case *types.Array: + id := fmt.Sprintf("_array_%d_%s", typ.Len(), getTypeString(typ.Elem())) + return "GoPy_" + id + + case *types.Slice: + id := fmt.Sprintf("_slice_%s", getTypeString(typ.Elem())) + return "GoPy_" + id + + } + + return fmt.Sprintf("%#T", typ) +}