Next: Type Checking of Foreign Objects, Previous: Defining Foreign Object Types, Up: Defining New Foreign Object Types [Contents][Index]
Foreign objects contain zero or more “slots” of data. A slot can hold
a pointer, an integer that fits into a size_t or ssize_t,
or a SCM value.
All objects of a given foreign type have the same number of slots. In
the example from the previous section, the image type has one
slot, because the slots list passed to
scm_make_foreign_object_type is of length one. (The actual names
given to slots are unimportant for most users of the C interface, but
can be used on the Scheme side to introspect on the foreign object.)
To construct a foreign object and initialize its first slot, call
scm_make_foreign_object_1 (type, first_slot_value).
There are similarly named constructors for initializing 0, 1, 2, or 3
slots, or initializing n slots via an array. See Foreign Objects, for full details. Any fields that are not explicitly
initialized are set to 0.
To get or set the value of a slot by index, you can use the
scm_foreign_object_ref and scm_foreign_object_set_x
functions. These functions take and return values as void *
pointers; there are corresponding convenience procedures like
_signed_ref, _unsigned_set_x and so on for dealing with
slots as signed or unsigned integers.
Foreign objects fields that are pointers can be tricky to manage. If possible, it is best that all memory that is referenced by a foreign object be managed by the garbage collector. That way, the GC can automatically ensure that memory is accessible when it is needed, and freed when it becomes inaccessible. If this is not the case for your program – for example, if you are exposing an object to Scheme that was allocated by some other, Guile-unaware part of your program – then you will probably need to implement a finalizer. See Foreign Object Memory Management, for more.
Continuing the example from the previous section, if the global variable
image_type contains the type returned by
scm_make_foreign_object_type, here is how we could construct a
foreign object whose “data” field contains a pointer to a freshly
allocated struct image:
SCM
make_image (SCM name, SCM s_width, SCM s_height)
{
struct image *image;
int width = scm_to_int (s_width);
int height = scm_to_int (s_height);
/* Allocate the `struct image'. Because we
use scm_gc_malloc, this memory block will
be automatically reclaimed when it becomes
inaccessible, and its members will be traced
by the garbage collector. */
image = (struct image *)
scm_gc_malloc (sizeof (struct image), "image");
image->width = width;
image->height = height;
/* Allocating the pixels with
scm_gc_malloc_pointerless means that the
pixels data is collectable by GC, but
that GC shouldn't spend time tracing its
contents for nested pointers because there
aren't any. */
image->pixels =
scm_gc_malloc_pointerless (width * height, "image pixels");
image->name = name;
image->update_func = SCM_BOOL_F;
/* Now wrap the struct image* in a new foreign
object, and return that object. */
return scm_make_foreign_object_1 (image_type, image);
}
We use scm_gc_malloc_pointerless for the pixel buffer to tell the
garbage collector not to scan it for pointers. Calls to
scm_gc_malloc, scm_make_foreign_object_1, and
scm_gc_malloc_pointerless raise an exception in out-of-memory
conditions; the garbage collector is able to reclaim previously
allocated memory if that happens.
Next: Type Checking of Foreign Objects, Previous: Defining Foreign Object Types, Up: Defining New Foreign Object Types [Contents][Index]