diff --git a/Examples/test-suite/go/go_inout_runme.go b/Examples/test-suite/go/go_inout_runme.go index 2dc5b9908..84dec7a0b 100644 --- a/Examples/test-suite/go/go_inout_runme.go +++ b/Examples/test-suite/go/go_inout_runme.go @@ -50,4 +50,8 @@ func main() { fmt.Println("for c2.M got", pm, "want", want) panic(pm) } + + c1 := go_inout.NewC1() + c2.M2(c1) + c2.M2(nil) } diff --git a/Examples/test-suite/go_inout.i b/Examples/test-suite/go_inout.i index 0bcb979ef..bb73f1b90 100644 --- a/Examples/test-suite/go_inout.i +++ b/Examples/test-suite/go_inout.i @@ -239,5 +239,7 @@ class C1 { }; class C2 : public C1 { + public: + void M2(C1*) {} }; %} diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg index c3401b1a8..90685ab95 100644 --- a/Lib/go/goruntime.swg +++ b/Lib/go/goruntime.swg @@ -149,6 +149,17 @@ type _swig_fnptr *byte type _swig_memberptr *byte %} +/* Convert a Go interface value into a C++ pointer. */ + +%insert(go_header) %{ +func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr { + if v == nil { + return 0 + } + return v.Swigcptr() +} +%} + /* For directors we need C++ to track a Go pointer. Since we can't pass a Go pointer into C++, we use a map to track the pointers on the Go side. */ diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 12f0dd747..c2e95228d 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1262,9 +1262,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); Setattr(p, "emit:goinput", ln); @@ -2506,7 +2512,7 @@ private: Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL); Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL); - Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(p.Swigcptr())\n", NULL); + Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL); Printv(f_go_wrappers, "}\n\n", NULL); Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL); @@ -2708,7 +2714,7 @@ private: Printv(f_go_wrappers, "}\n\n", NULL); Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL); - Printv(f_go_wrappers, "\treturn p.", go_type_name, ".Swigcptr()\n", NULL); + Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL); Printv(f_go_wrappers, "}\n\n", NULL); Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL); @@ -2866,9 +2872,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3461,9 +3473,15 @@ private: // the goin typemap. String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3709,9 +3727,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3830,7 +3854,7 @@ private: if (SwigType_type(result) != T_VOID) { Printv(call, "swig_r = ", NULL); if (result_is_interface) { - Printv(call, result_wrapper, "(", NULL); + Printv(call, result_wrapper, "(getSwigcptr(", NULL); } } Printv(call, "swig_p.", go_with_over_name, "(", NULL); @@ -3890,7 +3914,7 @@ private: Printv(call, ")", NULL); if (result_is_interface) { - Printv(call, ".Swigcptr())", NULL); + Printv(call, "))", NULL); } Printv(call, "\n", NULL);