Skip to content
This repository was archived by the owner on Aug 13, 2019. It is now read-only.

Commit db3f52b

Browse files
committed
Switch the Native method to return a uintptr.
This change modifies the function signature of the various Native methods from returing a C pointer to returning a uintptr. This change is being made for the following reasons: 1) cgo's psuedo package qualifier is replaced with the package local prefix `_Ctype_'. Because these prefixes are package local, it is impossible to use the returned pointer directly in data structures without first type switching the result with the unsafe package. When the caller is not interested in using the pointer for other cgo calls (for example, creating a map of GObjects to Go structs to look up additional context from callbacks), returning a uintptr does not require any additional type switches, and more importantly does not require the use of the unsafe package. 2) When the returned pointer is meant to be used as an argument to a cgo function, the returned result must fisrt be type switched to a package-local C type using the unsafe package. While returning a uintptr does not make this process any easier, it also doesn't make it any more inconvenient.
1 parent 753a34f commit db3f52b

File tree

8 files changed

+1060
-983
lines changed

8 files changed

+1060
-983
lines changed

cairo/cairo.go

Lines changed: 82 additions & 72 deletions
Large diffs are not rendered by default.

gdk/gdk.go

Lines changed: 91 additions & 56 deletions
Large diffs are not rendered by default.

glib/glib.go

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func (v *Object) Connect(detailedSignal string, f interface{}, userData ...inter
166166

167167
C._g_closure_add_finalize_notifier(closure)
168168

169-
c := C.g_signal_connect_closure(C.gpointer(v.Native()),
169+
c := C.g_signal_connect_closure(C.gpointer(v.native()),
170170
(*C.gchar)(cstr), closure, gbool(false))
171171
handle := SignalHandle(c)
172172

@@ -287,7 +287,7 @@ func goMarshal(closure *C.GClosure, retValue *C.GValue,
287287
fmt.Fprintf(os.Stderr,
288288
"cannot save callback return value: %v", err)
289289
} else {
290-
*retValue = *g.Native()
290+
*retValue = *g.native()
291291
}
292292
}
293293
}
@@ -436,7 +436,7 @@ func (v *Object) toGObject() *C.GObject {
436436
if v == nil {
437437
return nil
438438
}
439-
return v.Native()
439+
return v.native()
440440
}
441441

442442
func (v *Object) toObject() *Object {
@@ -448,23 +448,28 @@ func newObject(p *C.GObject) *Object {
448448
return &Object{GObject: p}
449449
}
450450

451-
// Native returns a pointer to the underlying GObject.
452-
func (v *Object) Native() *C.GObject {
451+
// native returns a pointer to the underlying GObject.
452+
func (v *Object) native() *C.GObject {
453453
if v == nil || v.GObject == nil {
454454
return nil
455455
}
456456
p := unsafe.Pointer(v.GObject)
457457
return C.toGObject(p)
458458
}
459459

460+
// Native returns a pointer to the underlying GObject.
461+
func (v *Object) Native() uintptr {
462+
return uintptr(unsafe.Pointer(v.native()))
463+
}
464+
460465
// IsA is a wrapper around g_type_is_a().
461466
func (v *Object) IsA(typ Type) bool {
462467
return gobool(C.g_type_is_a(C.GType(v.TypeFromInstance()), C.GType(typ)))
463468
}
464469

465470
// TypeFromInstance is a wrapper around g_type_from_instance().
466471
func (v *Object) TypeFromInstance() Type {
467-
c := C._g_type_from_instance(C.gpointer(unsafe.Pointer(v.Native())))
472+
c := C._g_type_from_instance(C.gpointer(unsafe.Pointer(v.native())))
468473
return Type(c)
469474
}
470475

@@ -641,13 +646,13 @@ func (v *Object) Emit(s string, args ...interface{}) (interface{}, error) {
641646
if err != nil {
642647
return nil, errors.New("Error converting Object to GValue: " + err.Error())
643648
}
644-
C.val_list_insert(valv, C.int(0), val.Native())
649+
C.val_list_insert(valv, C.int(0), val.native())
645650
for i := range args {
646651
val, err := GValue(args[i])
647652
if err != nil {
648653
return nil, fmt.Errorf("Error converting arg %d to GValue: %s", i, err.Error())
649654
}
650-
C.val_list_insert(valv, C.int(i+1), val.Native())
655+
C.val_list_insert(valv, C.int(i+1), val.native())
651656
}
652657

653658
t := v.TypeFromInstance()
@@ -658,7 +663,7 @@ func (v *Object) Emit(s string, args ...interface{}) (interface{}, error) {
658663
if err != nil {
659664
return nil, errors.New("Error creating Value for return value")
660665
}
661-
C.g_signal_emitv(valv, id, C.GQuark(0), ret.Native())
666+
C.g_signal_emitv(valv, id, C.GQuark(0), ret.native())
662667

663668
return ret.GoValue()
664669
}
@@ -687,9 +692,22 @@ func (v *Object) HandlerDisconnect(handle SignalHandle) {
687692

688693
// InitiallyUnowned is a representation of GLib's GInitiallyUnowned.
689694
type InitiallyUnowned struct {
695+
// This must be a pointer so copies of the ref-sinked object
696+
// do not outlive the original object, causing an unref
697+
// finalizer to prematurely run.
690698
*Object
691699
}
692700

701+
// Native returns a pointer to the underlying GObject. This is implemented
702+
// here rather than calling Native on the embedded Object to prevent a nil
703+
// pointer dereference.
704+
func (v *InitiallyUnowned) Native() uintptr {
705+
if v == nil || v.Object == nil {
706+
return uintptr(unsafe.Pointer(nil))
707+
}
708+
return v.Object.Native()
709+
}
710+
693711
/*
694712
* GSList
695713
*/
@@ -714,11 +732,16 @@ type Value struct {
714732
GValue C.GValue
715733
}
716734

717-
// Native returns a pointer to the underlying GValue.
718-
func (v *Value) Native() *C.GValue {
735+
// native returns a pointer to the underlying GValue.
736+
func (v *Value) native() *C.GValue {
719737
return &v.GValue
720738
}
721739

740+
// Native returns a pointer to the underlying GValue.
741+
func (v *Value) Native() uintptr {
742+
return uintptr(unsafe.Pointer(v.native()))
743+
}
744+
722745
// ValueAlloc allocates a Value and sets a runtime finalizer to call
723746
// g_value_unset() on the underlying GValue after leaving scope.
724747
// ValueAlloc() returns a non-nil error if the allocation failed.
@@ -747,17 +770,17 @@ func ValueInit(t Type) (*Value, error) {
747770
}
748771

749772
func (v *Value) unset() {
750-
C.g_value_unset(v.Native())
773+
C.g_value_unset(v.native())
751774
}
752775

753776
// Type is a wrapper around the G_VALUE_HOLDS_GTYPE() macro and
754777
// the g_value_get_gtype() function. GetType() returns TYPE_INVALID if v
755778
// does not hold a Type, or otherwise returns the Type of v.
756779
func (v *Value) Type() (actual Type, fundamental Type, err error) {
757-
if !gobool(C._g_is_value(v.Native())) {
780+
if !gobool(C._g_is_value(v.native())) {
758781
return actual, fundamental, errors.New("invalid GValue")
759782
}
760-
cActual := C._g_value_type(v.Native())
783+
cActual := C._g_value_type(v.native())
761784
cFundamental := C._g_value_fundamental(cActual)
762785
return Type(cActual), Type(cFundamental), nil
763786
}
@@ -1091,7 +1114,7 @@ func (v *Value) GoValue() (interface{}, error) {
10911114
return nil, err
10921115
}
10931116

1094-
rv, err := f(uintptr(unsafe.Pointer(v.Native())))
1117+
rv, err := f(uintptr(unsafe.Pointer(v.native())))
10951118
if obj, ok := rv.(IObject); ok {
10961119
o := obj.toObject()
10971120
o.RefSink()
@@ -1102,72 +1125,72 @@ func (v *Value) GoValue() (interface{}, error) {
11021125

11031126
// SetBool is a wrapper around g_value_set_boolean().
11041127
func (v *Value) SetBool(val bool) {
1105-
C.g_value_set_boolean(v.Native(), gbool(val))
1128+
C.g_value_set_boolean(v.native(), gbool(val))
11061129
}
11071130

11081131
// SetSChar is a wrapper around g_value_set_schar().
11091132
func (v *Value) SetSChar(val int8) {
1110-
C.g_value_set_schar(v.Native(), C.gint8(val))
1133+
C.g_value_set_schar(v.native(), C.gint8(val))
11111134
}
11121135

11131136
// SetInt64 is a wrapper around g_value_set_int64().
11141137
func (v *Value) SetInt64(val int64) {
1115-
C.g_value_set_int64(v.Native(), C.gint64(val))
1138+
C.g_value_set_int64(v.native(), C.gint64(val))
11161139
}
11171140

11181141
// SetInt is a wrapper around g_value_set_int().
11191142
func (v *Value) SetInt(val int) {
1120-
C.g_value_set_int(v.Native(), C.gint(val))
1143+
C.g_value_set_int(v.native(), C.gint(val))
11211144
}
11221145

11231146
// SetUChar is a wrapper around g_value_set_uchar().
11241147
func (v *Value) SetUChar(val uint8) {
1125-
C.g_value_set_uchar(v.Native(), C.guchar(val))
1148+
C.g_value_set_uchar(v.native(), C.guchar(val))
11261149
}
11271150

11281151
// SetUInt64 is a wrapper around g_value_set_uint64().
11291152
func (v *Value) SetUInt64(val uint64) {
1130-
C.g_value_set_uint64(v.Native(), C.guint64(val))
1153+
C.g_value_set_uint64(v.native(), C.guint64(val))
11311154
}
11321155

11331156
// SetUInt is a wrapper around g_value_set_uint().
11341157
func (v *Value) SetUInt(val uint) {
1135-
C.g_value_set_uint(v.Native(), C.guint(val))
1158+
C.g_value_set_uint(v.native(), C.guint(val))
11361159
}
11371160

11381161
// SetFloat is a wrapper around g_value_set_float().
11391162
func (v *Value) SetFloat(val float32) {
1140-
C.g_value_set_float(v.Native(), C.gfloat(val))
1163+
C.g_value_set_float(v.native(), C.gfloat(val))
11411164
}
11421165

11431166
// SetDouble is a wrapper around g_value_set_double().
11441167
func (v *Value) SetDouble(val float64) {
1145-
C.g_value_set_double(v.Native(), C.gdouble(val))
1168+
C.g_value_set_double(v.native(), C.gdouble(val))
11461169
}
11471170

11481171
// SetString is a wrapper around g_value_set_string().
11491172
func (v *Value) SetString(val string) {
11501173
cstr := C.CString(val)
11511174
defer C.free(unsafe.Pointer(cstr))
1152-
C.g_value_set_string(v.Native(), (*C.gchar)(cstr))
1175+
C.g_value_set_string(v.native(), (*C.gchar)(cstr))
11531176
}
11541177

11551178
// SetInstance is a wrapper around g_value_set_instance().
11561179
func (v *Value) SetInstance(instance uintptr) {
1157-
C.g_value_set_instance(v.Native(), C.gpointer(instance))
1180+
C.g_value_set_instance(v.native(), C.gpointer(instance))
11581181
}
11591182

11601183
// SetPointer is a wrapper around g_value_set_pointer().
11611184
func (v *Value) SetPointer(p uintptr) {
1162-
C.g_value_set_pointer(v.Native(), C.gpointer(p))
1185+
C.g_value_set_pointer(v.native(), C.gpointer(p))
11631186
}
11641187

11651188
// GetString is a wrapper around g_value_get_string(). GetString()
11661189
// returns a non-nil error if g_value_get_string() returned a NULL
11671190
// pointer to distinguish between returning a NULL pointer and returning
11681191
// an empty string.
11691192
func (v *Value) GetString() (string, error) {
1170-
c := C.g_value_get_string(v.Native())
1193+
c := C.g_value_get_string(v.native())
11711194
if c == nil {
11721195
return "", errNilPtr
11731196
}

gtk/examples/boolprops/boolprops.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ func main() {
6262
}
6363

6464
setupPropertyCheckboxes(tv, box, props)
65-
box.PackStart(tv, true, true, 0)
6665

6766
win.ShowAll()
6867

0 commit comments

Comments
 (0)