(guile.info.gz) Creating Instances
Info Catalog
(guile.info.gz) Describing a New Type
(guile.info.gz) Defining New Types (Smobs)
(guile.info.gz) Type checking
18.3.2 Creating Instances
-------------------------
Like other non-immediate types, smobs start with a cell whose first word
contains typing information, and whose remaining words are free for any
use.
After the header word containing the type code, smobs can have either
one, two or three additional words of data. These words store either a
pointer to the internal C structure holding the smob-specific data, or
the smob data itself. To create an instance of a smob type following
these standards, you should use `SCM_NEWSMOB', `SCM_NEWSMOB2' or
`SCM_NEWSMOB3':(1)
-- Macro: void SCM_NEWSMOB (SCM value, scm_t_bits tag, void *data)
-- Macro: void SCM_NEWSMOB2 (SCM value, scm_t_bits tag, void *data1,
void *data2)
-- Macro: void SCM_NEWSMOB3 (SCM value, scm_t_bits tag, void *data1,
void *data2, void *data3)
Make VALUE contain a smob instance of the type with tag TAG and
smob data DATA (or DATA1, DATA2, and DATA3). VALUE must be
previously declared as C type `SCM'.
Since it is often the case (e.g., in smob constructors) that you will
create a smob instance and return it, there is also a slightly
specialized macro for this situation:
-- Macro: fn_returns SCM_RETURN_NEWSMOB (scm_t_bits tag, void *data)
-- Macro: fn_returns SCM_RETURN_NEWSMOB2 (scm_t_bits tag, void *data1,
void *data2)
-- Macro: fn_returns SCM_RETURN_NEWSMOB3 (scm_t_bits tag, void *data1,
void *data2, void *data3)
This macro expands to a block of code that creates a smob instance
of the type with tag TAG and smob data DATA (or DATA1, DATA2, and
DATA3), and causes the surrounding function to return that `SCM'
value. It should be the last piece of code in a block.
Guile provides the following functions for managing memory, which are
often helpful when implementing smobs:
-- Function: char * scm_must_malloc (size_t LEN, char *WHAT)
Allocate LEN bytes of memory, using `malloc', and return a pointer
to them.
If there is not enough memory available, invoke the garbage
collector, and try once more. If there is still not enough,
signal an error, reporting that we could not allocate WHAT.
This function also helps maintain statistics about the size of the
heap.
-- Function: char * scm_must_realloc (char *ADDR, size_t OLEN, size_t
LEN, char *WHAT)
Resize (and possibly relocate) the block of memory at ADDR, to
have a size of LEN bytes, by calling `realloc'. Return a pointer
to the new block.
If there is not enough memory available, invoke the garbage
collector, and try once more. If there is still not enough,
signal an error, reporting that we could not allocate WHAT.
The value OLEN should be the old size of the block of memory at
ADDR; it is only used for keeping statistics on the size of the
heap.
-- Function: void scm_must_free (char *ADDR)
Free the block of memory at ADDR, using `free'. If ADDR is zero,
signal an error, complaining of an attempt to free something that
is already free.
This does no record-keeping; instead, the smob's `free' function
must take care of that.
This function isn't usually sufficiently different from the usual
`free' function to be worth using.
Continuing the above example, if the global variable `image_tag'
contains a tag returned by `scm_make_smob_type', here is how we could
construct a smob whose CDR contains a pointer to a freshly allocated
`struct image':
struct image {
int width, height;
char *pixels;
/* The name of this image */
SCM name;
/* A function to call when this image is
modified, e.g., to update the screen,
or SCM_BOOL_F if no action necessary */
SCM update_func;
};
SCM
make_image (SCM name, SCM s_width, SCM s_height)
{
struct image *image;
int width, height;
SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1, "make-image");
SCM_ASSERT (SCM_INUMP (s_width), s_width, SCM_ARG2, "make-image");
SCM_ASSERT (SCM_INUMP (s_height), s_height, SCM_ARG3, "make-image");
width = SCM_INUM (s_width);
height = SCM_INUM (s_height);
image = (struct image *) scm_must_malloc (sizeof (struct image), "image");
image->width = width;
image->height = height;
image->pixels = scm_must_malloc (width * height, "image pixels");
image->name = name;
image->update_func = SCM_BOOL_F;
SCM_RETURN_NEWSMOB (image_tag, image);
}
---------- Footnotes ----------
(1) The `SCM_NEWSMOB2' and `SCM_NEWSMOB3' variants will allocate
double cells and thus use twice as much memory as smobs created by
`SCM_NEWSMOB'.
Info Catalog
(guile.info.gz) Describing a New Type
(guile.info.gz) Defining New Types (Smobs)
(guile.info.gz) Type checking
automatically generated byinfo2html