On this page:
4.1 Basic Usage
4.2 GIRepository
introspection
gi-repository
gi-repository-find-name
gi-repository->ffi-lib
gir-member/  c
gi-repository-member/  c
4.3 GIBase  Info
gi-base
gi-function
gi-constant
gi-struct
gi-object
gi-enum
gi-base-name
gi-base=?
gi-function?
gi-registered-type?
gi-enum?
gi-bitmask?
gi-enum->list
gi-enum->hash
gi-enum-value/  c
gi-bitmask-value/  c
gi-object?
gi-struct?
_  gi-object
gi-instance
gi-instance-name
is-gtype?
is-gtype?/  c
gtype?
gtype-name
gstruct
4.4 GObjects
gobject?
gobject/  c
gobject-ptr
gobject=?
gobject-gtype
gobject-send
gobject-get-field
gobject-set-field!
gobject-responds-to?
gobject-responds-to?/  c
method-names
connect
gobject-cast
gobject-get
gobject-set!
gobject-with-properties
make-gobject-property-procedures
prop:  gobject
gobject<%>
gobject%
new
make-gobject-delegate
7.7

4 GObject Introspection

GStreamer is the core framework that powers the multimedia capabilities of Overscan. GStreamer is also a C framework, which means that a big part of Overscan’s codebase is dedicated to the interop between Racket and C. Racket provides a phenomenal Foreign Interface, but to create foreign functions for all the relevant portions of GStreamer would be cumbersome, at best.

Luckily, GStreamer is written with GLib and contains GObject Introspection metadata. GObject Introspection (aka GIR) is an interface description layer that allows for a language to read this metadata and dynamically create bindings for the C library.

The Overscan package provides a module designed to accompany Racket’s FFI collection. This module brings additional functionality and C Types for working with introspected C libraries. This module powers the GStreamer module, but can be used outside of Overscan for working with other GLib libraries.

 (require ffi/unsafe/introspection) package: overscan

4.1 Basic Usage

Using GIR will typically go as follows: Introspect a namespace that you have a typelib for with introspection, call that namespace as a procedure to look up a binding, work with that binding either as a procedure or some other value (typically a gobject).

In this case of a typical "Hello, world" style example with GStreamer, that would look like this:

(define gst (introspection 'Gst))
(define gst-version (gst 'version_string))
(printf "This program is linked against ~a"
        (gst-version))

This will result in the string "This program is linked against GStreamer 1.10.4" being printed, or whatever version of GStreamer is available.

In the second line of this program, the 'version_string symbol is looked up against the GStreamer typelib and a gi-function? is returned. That can then be called as a procedure, which in this case takes no arguments.

4.2 GIRepository

GIR’s GIRepository API manages the namespaces provided by the GIR system and type libraries. Each namespace contains metadata entries that map to C functionality. In the case of GStreamer, the 'Gst namespace contains all of the introspection information used to power that interface.

procedure

(introspection namespace [version])  gi-repository?

  namespace : symbol?
  version : string? = #f
Search for the namespace typelib in the GObject Introspection repository search path and load it. If version is not specified, the latest version will be used.

An example for loading the GStreamer namespace:

> (define gst (introspection 'Gst))
  #<procedure:gi-repository>

This is the only provided mechanism to construct a gi-repository.

struct

(struct gi-repository (namespace version info-hash))

  namespace : symbol?
  version : string?
  info-hash : (hash/c symbol? gi-base?)
A struct representing a namespace of an introspected typelib. This struct is constructed bye calling introspection. This struct has the prop:procedure property and is intended to be called as a procedure:

gi-repository

(repository)  (hash/c symbol? gi-base?)

(repository name)  gi-base?
  name : symbol?
When called as in the first form, without an argument, the proc will return a hash of all of the known members of the namespace.

When called as the second form, this is the equivalent to gi-repository-find-name with the first argument already set. e.g.

> (gst 'version)
  #<procedure:gi-function>

This will return an introspected foreign binding to the gst_version() C function, represented as a gi-function?.

procedure

(gi-repository-find-name repo name)  gi-base?

  repo : gi-repository?
  name : symbol?
Find a metadata entry called name in the repo. These entries form the basis of the foreign interface. This will raise an exn:fail:contract exception if the entry is not a part of the given namespace.

procedure

(gi-repository->ffi-lib repo)  ffi-lib?

  repo : gi-repository?
Lookup the library path of a repository and return a foreign-library value

procedure

(gir-member/c namespace)  flat-contract?

  namespace : symbol?
Accepts a GIR namespace and returns a flat contract that recognizes a symbol within that namespace. Use this to check for whether or not an entry is a member of a namespace.

procedure

(gi-repository-member/c repo)  flat-contract?

  repo : gi-repository?
Equivalent to gir-member/c except with a repository struct (as returned by introspection) instead of a namespace.

4.3 GIBaseInfo

The GIBaseInfo C Struct is the base struct for all GIR metadata entries. Whenever you do some lookup within GIR, what’s returned is an instance of a descendant from this struct. The gi-base struct is the Racket equivalent, and introspection will return entities that inherit from this base struct.

struct

(struct gi-base (info))

  info : cpointer?
The common base struct of all GIR metadata entries. Instances of this struct have the prop:cpointer property, and can be used transparently as cpointers to their respective entries. This struct and its descendants are constructed by looking up a symbol on a gi-repository.

When a GIR metadata entry is located it will usually be a subtype of gi-base. Most of those subtypes implement prop:procedure and are designed to be called on return to produce meaningful values.

The typical subtypes are:

gi-base

(gi-function arg ...)  any

  arg : any/c
An introspected C function. Call this as you would any other Racket procedure. C functions have a tendency to mutate call-by-reference pointers, and when that is the case calling a gi-function returns multiple values. The first return value is always the return value of the function.

gi-base

(gi-constant)  any/c

Calling a gi-constant as a procedure returns its value.

gi-registered-type

(gi-struct method-name arg ...)  any

  method-name : symbol?
  arg : any/c
The first argument to a gi-struct is the name of a method, with subsequent arguments passed in to that method call. This procedure form is mainly used for calling factory style methods, and more useful for the similar gi-object. Usually, you’ll be working with instances of this type, gstructs.

gi-registered-type

(gi-object method-name arg ...)  any

  method-name : symbol?
  arg : any/c
Like gi-struct, calling a gi-object as a procedure will accept a method name and subsequent arguments. This is the preferred form for calling constructors that will return gobjects.

gi-registered-type

gi-enum : gi-enum?

A gi-enum represents an enumeration of values and, unlike other gi-base subtypes, is not represented as a procedure. The main use case is to transform it into some other Racket representation, i.e. with gi-enum->list.

procedure

(gi-base-name info)  symbol?

  info : gi-base?
Obtain the name of the info.

procedure

(gi-base=? a b)  boolean?

  a : gi-base?
  b : gi-base?
Compare two gi-bases. Doing pointer comparison or other equality comparisons does not work. This function compares two entries of the typelib.

procedure

(gi-function? v)  boolean?

  v : any/c
A GIFunctionInfo struct inherits from GIBaseInfo and represents a C function. Returns #t if v is a Function Info, #f otherwise.

procedure

(gi-registered-type? v)  boolean?

  v : any/c
A GIRegisteredTypeInfo struct inherits from GIBaseInfo. An entry of this type represents some C entity with an associated GType. Returns #t if v is a Registered Type, #f otherwise.

procedure

(gi-enum? v)  boolean?

  v : any/c
A GIEnumInfo is an introspected entity representing an enumeration. Returns #t if v is an Enumeration, #f otherwise.

procedure

(gi-bitmask? v)  boolean?

  v : any/c
Returns #t if v is a gi-enum? but is represented as a bitmask in C.

procedure

(gi-enum->list enum)  list?

  enum : gi-enum?
Convert enum to a list of symbols, representing the values of the enumeration.

procedure

(gi-enum->hash enum)  hash?

  enum : gi-enum?
Convert enum to a hash mapping symbols to their numeric value.

procedure

(gi-enum-value/c enum)  flat-contract?

  enum : gi-enum?
Accepts a gi-enum and returns a flat contract that recognizes its values.

procedure

(gi-bitmask-value/c enum)  list-contract?

  enum : gi-bitmask?
Accepts a bitmask gi-enum and returns a contract that recognizes a list of allowed values.

procedure

(gi-object? v)  boolean?

  v : any/c
A GIObjectInfo is an introspected entity representing a GObject. This does not represent an instance of a GObject, but instead represents a GObject’s type information (roughly analogous to a "class"). Returns #t if v is a GIObjectInfo, #f otherwise.

See GObjects for more information about using GObjects from within Racket.

procedure

(gi-struct? v)  boolean?

  v : any/c
A GIStructInfo is an introspected entity representing a C Struct. Returns #t if v is a GIStructInfo, #f otherwise.

procedure

(_gi-object obj)  ctype?

  obj : gi-object?
Constructs a ctype for the given obj, which is effectively a _cpointer that will dereference into an instance of the obj.

struct

(struct gi-instance (type pointer))

  type : gi-registered-type?
  pointer : cpointer?
Represents an instance of a GType type. This struct and its descendants have the prop:cpointer property, and can be used as a pointer in FFI calls. Registered type instances can have methods and fields associated with them.

procedure

(gi-instance-name instance)  symbol?

  instance : gi-instance?
Returns the name of the type of instance.

procedure

(is-gtype? v type)  boolean?

  v : any/c
  type : gi-registered-type?
Returns #t if v is an instance of type, #f otherwise. Similar to is-a?.

procedure

(is-gtype?/c type)  flat-contract?

  type : gi-registered-type?
Accepts a type and returns a flat contract that recognizes its instances.

procedure

(gtype? v)  boolean?

  v : any/c
Returns #t if v is a valid GType, #f otherwise.

procedure

(gtype-name gtype)  symbol?

  gtype : gtype?
Gets the unique name that is assigned to gtype.

struct

(struct gstruct gi-instance (type pointer))

  type : gi-struct?
  pointer : cpointer?
Represents an instance of a C Struct. That Struct can have methods and fields.

4.4 GObjects

A gobject instance, like the introspected metadata entries provided by GIR, is a transparent pointer with additional utilities to be called as an object within Racket. GObjects behave like Racket objects, with the exception that they aren’t backed by classes in the racket/class sense, but instead are derived from the introspected metadata.

procedure

(gobject? v)  boolean?

  v : any/c
Returns #t if v is an instance of a GObject, #f otherwise. You can call methods, get or set fields, get/set properties, or connect to signals on a GObject. gstruct structs are also GObjects for the purposes of this predicate, since they behave in similar ways with the exception of signals and properties.

procedure

(gobject/c type)  flat-contract?

  type : gi-registered-type?
Accepts a type and returns a flat contract that recognizes objects that instantiate it. Unlike is-gtype?/c, this implies gobject?.

procedure

(gobject-ptr obj)  gi-instance?

  obj : gobject?
Returns the gi-instance associated with obj.

procedure

(gobject=? obj1 obj2)  boolean?

  obj1 : gobject?
  obj2 : gobject?
Compares the values of two GObjects. Two different gobjects can contain the same reference. This effectively does pointer comparison using ptr-equal?.

procedure

(gobject-gtype obj)  gtype?

  obj : gobject?
Returns the GType of obj.

procedure

(gobject-send obj method-name argument ...)  any

  obj : gobject?
  method-name : symbol?
  argument : any/c
Calls the method on obj whose name matches method-name, passing along all given arguments.

procedure

(gobject-get-field field-name obj)  any

  field-name : symbol?
  obj : gobject?
Extracts the field from obj whose name matches field-name. Note that fields are distinct from GObject properties, which are accessed with gobject-get.

procedure

(gobject-set-field! field-name obj v)  void?

  field-name : symbol?
  obj : gobject?
  v : any/c
Sets the field from obj whose name matches field-name to v.

procedure

(gobject-responds-to? obj method-name)  boolean?

  obj : gobject?
  method-name : symbol?
Produces #t if obj or its ancestors defines a method with the name method-name, #f otherwise.

procedure

(gobject-responds-to?/c method-name)  flat-contract?

  method-name : symbol?
Accepts a method-name and returns a flat contract that recognizes objects with a method defined with the given name in it or its ancestors. Useful for duck-typing.

procedure

(method-names obj)  (listof symbol?)

  obj : gobject?
Extracts a list that obj recognizes as names of methods it understands. This list might not be exhaustive.

procedure

(connect obj    
  signal-name    
  handler    
  [#:data data    
  #:cast _user-data])  exact-integer?
  obj : gobject?
  signal-name : symbol?
  handler : procedure?
  data : any/c = #f
  _user-data : (or/c ctype? gi-object?) = #f
Register a callback handler for the signal matching the name signal-name for the obj. The handler will receive three arguments, obj, the name of the signal as a string, and data. When both are present, data will be cast to _user-data before being passed to the handler.

procedure

(gobject-cast pointer obj)  gobject?

  pointer : cpointer?
  obj : gi-object?
This will cast pointer to (_gi-object obj), thereby transforming it into a gobject.

procedure

(gobject-get obj propname ctype)  any?

  obj : gobject?
  propname : string?
  ctype : (or/c ctype? gi-registered-type? (listof symbol?))
Extract the property from obj whose name matches propname and can be dereferenced as a ctype.

procedure

(gobject-set! obj propname v [ctype])  void?

  obj : gobject?
  propname : string?
  v : any/c
  ctype : (or/c ctype? (listof symbol?)) = #f
Sets the property of obj whose name matches propname to v. If ctype is a (listof symbol?), v is assumed to be a symbol in that list, used for representing _enums. If no ctype is provided, one is inferred based on v.

procedure

(gobject-with-properties obj properties)  gobject?

  obj : gobject?
  properties : (hash/c symbol? any/c)
Sets a group of properties on obj based on a hash and returns obj. Note that you cannot explicitly set the ctype of the properties with this form.

procedure

(make-gobject-property-procedures propname 
  ctype) 
  
(-> gobject? any)
(-> gobject? any/c void?)
  propname : string?
  ctype : (or/c ctype? gi-registered-type? (listof symbol?))
Accepts a propname and a ctype and creates and returns a gobject-property-accessor and a gobject-property-mutator. The accessor accepts a gobject and returns the value of the property with the name matching propname via gobject-get. The mutator accepts a gobject and a value and mutates the property matching propname via gobject-set!.

A convenient mechanism for creating a getter and a setter for a GObject property.

A structure type property that causes instances of a structure type to work as GObject instances. The property value must be either a gi-instance or a procedure that accepts the structure instance and returns a gi-instance.

The prop:gobject property allows a GObject instance to be transparently wrapped by a structure that may have additional values or properties.

interface

gobject<%> : interface?

A gobject<%> object encapsulates a gobject pointer. It looks for a field called pointer and will use that as a value for prop:gobject, so that objects implementing this interface return #t to gobject? and cpointer?.

class

gobject% : class?

  superclass: object%

  extends: gobject<%>
Instances of this class return #t to gobject?.

constructor

(new gobject% [pointer pointer])  (is-a?/c gobject%)

  pointer : gi-instance?

syntax

(make-gobject-delegate method-decl ...)

 
method-decl = id
  | (id internal-method)
 
  internal-method : symbol?
Create a mixin that defines a class extension that implements gobject<%>. The specified ids will be defined as public methods that delegate to the pointer. When internal-method is included, the expression is assumed to result in a symbol that will be used to look up the method in GIR. When no internal-method is provided, the method name used by GIR will be the id with dashes replaced with underscores.

e.g.

(make-gobject-delegate get-name get-factory [static-pad 'get_static_pad])

is equivalent to:
(mixin (gobject<%>) (gobject<%>)
  (super-new)
  (inherit-field pointer)
  (define/public (get-name . args)
    (apply gobject-send pointer 'get_name args))
  (define/public (get-factory . args)
    (apply gobject-send pointer 'get_factory args))
  (define/public (static-pad . args)
    (apply gobject-send pointer 'get_static_pad args)))