glib/glib.go
func goMarshal(closure *C.GClosure, retValue *C.GValue,
	nParams C.guint, params *C.GValue,
	invocationHint C.gpointer, marshalData *C.GValue) {

	// Get the context associated with this callback closure.
	closures.RLock()
	cc := closures.m[closure]
	closures.RUnlock()

	// Get number of parameters passed in.  If user data was saved with the
	// closure context, increment the total number of parameters.
	nGLibParams := int(nParams)
	nTotalParams := nGLibParams
	if cc.userData.IsValid() {
		nTotalParams++
	}

	// Get number of parameters from the callback closure.  If this exceeds
	// the total number of marshaled parameters, a warning will be printed
	// to stderr, and the callback will not be run.
	nCbParams := cc.rf.Type().NumIn()
	if nCbParams > nTotalParams {
		fmt.Fprintf(os.Stderr,
			"too many closure args: have %d, max allowed %d\n",
			nCbParams, nTotalParams)
		return
	}

	// Create a slice of reflect.Values as arguments to call the function.
	gValues := gValueSlice(params, nCbParams)
	args := make([]reflect.Value, 0, nCbParams)

	// Fill beginning of args, up to the minimum of the total number of callback
	// parameters and parameters from the glib runtime.
	for i := 0; i < nCbParams && i < nGLibParams; i++ {
		v := &Value{&gValues[i]}
		val, err := v.GoValue()
		if err != nil {
			fmt.Fprintf(os.Stderr,
				"no suitable Go value for arg %d: %v\n", i, err)
			return
		}
		// Parameters that are descendants of GObject come wrapped in another GObject.
		// For C applications, the default marshaller (g_cclosure_marshal_VOID__VOID in
		// gmarshal.c in the GTK glib library) 'peeks' into the enclosing object and
		// passes the wrapped object to the handler. Use the *Object.goValue function
		// to emulate that for Go signal handlers.
		switch objVal := val.(type) {
		case *Object:
			innerVal, err := objVal.goValue()
			if err != nil {
				// print warning and leave val unchanged to preserve old
				// behavior
				fmt.Fprintf(os.Stderr,
					"warning: no suitable Go value from object for arg %d: %v\n", i, err)
			} else {
				val = innerVal
			}
		}
		rv := reflect.ValueOf(val)
		args = append(args, rv.Convert(cc.rf.Type().In(i)))
	}

	// If non-nil user data was passed in and not all args have been set,
	// get and set the reflect.Value directly from the GValue.
	if cc.userData.IsValid() && len(args) < cap(args) {
		args = append(args, cc.userData.Convert(cc.rf.Type().In(nCbParams-1)))
	}

	// Call closure with args. If the callback returns one or more
	// values, save the GValue equivalent of the first.
	rv := cc.rf.Call(args)
	if retValue != nil && len(rv) > 0 {
		if g, err := GValue(rv[0].Interface()); err != nil {
			fmt.Fprintf(os.Stderr,
				"cannot save callback return value: %v", err)
		} else {
			*retValue = *g.native()
		}
	}
}
func goMarshal(closure *C.GClosure, retValue *C.GValue,
	nParams C.guint, params *C.GValue,
	invocationHint C.gpointer, marshalData *C.GValue) {

	// Get the context associated with this callback closure.
	closures.RLock()
	cc := closures.m[closure]
	closures.RUnlock()

	// Get number of parameters passed in.  If user data was saved with the
	// closure context, increment the total number of parameters.
	nGLibParams := int(nParams)
	nTotalParams := nGLibParams
	if cc.userData.IsValid() {
		nTotalParams++
	}

	// Get number of parameters from the callback closure.  If this exceeds
	// the total number of marshaled parameters, a warning will be printed
	// to stderr, and the callback will not be run.
	nCbParams := cc.rf.Type().NumIn()
	if nCbParams > nTotalParams {
		fmt.Fprintf(os.Stderr,
			"too many closure args: have %d, max allowed %d\n",
			nCbParams, nTotalParams)
		return
	}

	// Create a slice of reflect.Values as arguments to call the function.
	gValues := gValueSlice(params, nCbParams)
	args := make([]reflect.Value, 0, nCbParams)

	// Fill beginning of args, up to the minimum of the total number of callback
	// parameters and parameters from the glib runtime.
	for i := 0; i < nCbParams && i < nGLibParams; i++ {
		v := &Value{&gValues[i]}
		val, err := v.GoValue()
		if err != nil {
			fmt.Fprintf(os.Stderr,
				"no suitable Go value for arg %d: %v\n", i, err)
			return
		}
		// Parameters that are descendants of GObject come wrapped in another GObject.
		// For C applications, the default marshaller (g_cclosure_marshal_VOID__VOID in
		// gmarshal.c in the GTK glib library) 'peeks' into the enclosing object and
		// passes the wrapped object to the handler. Use the *Object.goValue function
		// to emulate that for Go signal handlers.
		switch objVal := val.(type) {
		case *Object:
			innerVal, err := objVal.goValue()
			if err != nil {
				// print warning and leave val unchanged to preserve old
				// behavior
				fmt.Fprintf(os.Stderr,
					"warning: no suitable Go value from object for arg %d: %v\n", i, err)
			} else {
				val = innerVal
			}
		}
		rv := reflect.ValueOf(val)
		args = append(args, rv.Convert(cc.rf.Type().In(i)))
	}

	// If non-nil user data was passed in and not all args have been set,
	// get and set the reflect.Value directly from the GValue.
	if cc.userData.IsValid() && len(args) < cap(args) {
		args = append(args, cc.userData.Convert(cc.rf.Type().In(nCbParams-1)))
	}

	// Call closure with args. If the callback returns one or more
	// values, save the GValue equivalent of the first.
	rv := cc.rf.Call(args)
	if retValue != nil && len(rv) > 0 {
		if g, err := GValue(rv[0].Interface()); err != nil {
			fmt.Fprintf(os.Stderr,
				"cannot save callback return value: %v", err)
		} else {
			*retValue = *g.native()
		}
	}
}
// goMarshal is called by the GLib runtime when a closure needs to be invoked.
// The closure will be invoked with as many arguments as it can take, from 0 to
// the full amount provided by the call. If the closure asks for more parameters
// than there are to give, a warning is printed to stderr and the closure is
// not run.
//
//export goMarshal