The
g-value structure is basically a variable container that consists
of a type identifier and a specific value of that type. The type identifier within a
g-value instance always determines the type of the associated value. To create a undefined
g-value instance, simply create a zero-filled
g-value instance. To initialize the
g-value instance, use the function
g-value-init. A
g-value
instance cannot be used until it is initialized. The basic type operations (such as freeing and copying) are determined by the
GTypeValueTable associated with the type ID stored in the
g-value instance. Other
g-value operations (such as converting values between types) are
provided by this interface.
The code in the example program below demonstrates
g-value's features.
;; A transformation from an integer to a string
(defcallback int2string :void ((src-value (:pointer (:struct g-value)))
(dest-value (:pointer (:struct g-value))))
(if (= (g-value-int src-value) 42)
(setf (g-value-string dest-value) "An important number")
(setf (g-value-string dest-value) "What is that?")))
(defun example-g-value ()
;; Declare two variables of type g-value.
(with-foreign-objects ((value1 'g-value) (value2 'g-value))
;; Initialization, setting and reading a value of type g-value
(g-value-init value1 +g-type-string+)
(setf (g-value-string value1) "string")
(format t "value1 = ~A~%" (g-value-string value1))
(format t "type = ~A~%" (g-value-type value1))
(format t "name = ~A~%~%" (g-value-type-name value1))
;; The same in one step with the Lisp extension set-g-value
(set-g-value value2 "a second string" +g-type-string+ :zero-g-value t)
(format t "value2 = ~A~%" (parse-g-value value2))
(format t "type = ~A~%" (g-value-type value2))
(format t "name = ~A~%~%" (g-value-type-name value2))
;; Reuse value1 for an integer value.
(g-value-unset value1)
(g-value-init value1 +g-type-int+)
(setf (g-value-int value1) 42)
(format t "value1 = ~A~%" (parse-g-value value1))
(format t "type = ~A~%" (g-value-type value1))
(format t "name = ~A~%~%" (g-value-type-name value1))
;; The types integer and string are transformable.
(assert (g-value-type-transformable +g-type-int+ +g-type-string+))
;; Transform value1 of type integer into value2 which is a string
(g-value-transform value1 value2)
(format t "value1 = ~A~%" (parse-g-value value1))
(format t "value2 = ~A~%~%" (parse-g-value value2))
;; Some test functions.
(assert (g-value-holds value1 +g-type-int+))
(format t "value-holds is ~A~%" (g-value-holds value1 +g-type-int+))
(format t "is-value is ~A~%~%" (g-type-is-value +g-type-int+))
;; Reuse value2 again for a string.
(g-value-unset value2)
(g-value-init value2 +g-type-string+)
(setf (g-value-string value2) "string")
(format t "value2 = ~A~%" (parse-g-value value2))
;; Register the transformation int2string
(g-value-register-transform-func "gint"
"gchararray"
(callback int2string))
;; Try the transformation
(g-value-transform value1 value2)
(format t "value2 = ~A~%~%" (parse-g-value value2))))
The data within the
g-value instance has protected scope: it is accessible only to functions within a
GTypeValueTable structure, or implementations of the
g-value-* API. That is, code portions which implement new fundamental types.
g-value users cannot make any
assumptions about how data is stored within the 2 element data union, and the
g-type member should only be accessed through the function
g-value-type.