This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: New smob interface


Klaus Schilling <Klaus.Schilling@home.ivm.de> writes:

> Would the following work for a wrapper for the ncurses library:
> 
> long WINDOW_type = scm_make_smob_type ("WINDOW_type", sizeof (WINDOW));
> #define SCM2WINDOW (x) ((WINDOW *)SCM_SMOB_DATA)

Should be:

#define SCM2WINDOW (x) ((WINDOW *)SCM_SMOB_DATA(x))

> scm_size_t WINDOW_free (SCM object)
> {
>   WINDOW *w;
>   w = SCM2WINDOW (object);
>   gh_defer_ints ();
>   delwin (w);
>   gh_allow_ints ();
>   return sizeof (WINDOW);
> }
> 
> 
> scm_set_smob_free (WINDOW_type, &WINDOW_free);
> 
> SCM WINDOW2SCM (WINDOW *w)
> {
>  SCM z;
>  SCM_NEWSMOB (z, WINDOW_type, w);
>  return z;
> }

This seems quite OK.

> Or does the fact that windows may contain pointers to other windows which
> are subject to guile's memory administration make it impossible to use
> scm_make_smob?

Hmm...  I'm not usre what you're asking.  Above you have chosen to use
SCM_NEWSMOB instead of scm_make_smob.  Since WINDOW structures don't
contain pointers to SCM objects, this is OK, but (warning: I'm not an
ncurses programmer) I suspect that the user never allocates the WINDOW
struct himself => you can only use SCM_NEWSMOB.

Or maybe you were wondering what happens if WINDOW w1 contains a
pointer to WINDOW w2 and w2 is freed before w1?

I don't think I'm the right person to respond to that question, but in
that case I would introduce another layer between the smob and the
WINDOW and let that structure contain a pointer to the handle of w2:

typedef struct WINDOW_wrapper {
  WINDOW *w;
  SCM windows;
} WINDOW_wrapper_t;

#define WINDOW_WRAPPER(x) ((WINDOW_wrapper_t *) SCM_SMOB_DATA (x))

SCM window2scm (WINDOW *w)
{
  SCM z;
  WINDOW_wrapper_t m = scm_must_malloc (sizeof (WINDOW_wrapper_t),
                                        "window2scm");
  m->w = w;
  m->windows = SCM_EOL;
  SCM_NEWSMOB (z, WINDOW_type, m);
  return z;
}

SCM WINDOW_mark (SCM obj)
{
  return WINDOW_WRAPPER (obj)->windows;
}

scm_set_smob_mark (WINDOW_type, WINDOW_mark);

When window w1 gets the dependency on w2 I'd add w2's handle (the SCM
object which contains w2) to w1's windows field.  This prevents GC of
w2 until w1 is freed.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]