DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH
 

(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