guile-gtk-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: g-wrap <gw-guile-wct> questions


From: Andy Wingo
Subject: Re: g-wrap <gw-guile-wct> questions
Date: Sun, 15 Aug 2004 10:58:20 +0100
User-agent: Mutt/1.5.6+20040803i

Hey Steve,

I'm not a wct expert. I usually use guile-gobject to handle that stuff,
which uses a combination of GOOPS objects and SMOBs. However...

On Thu, 12 Aug 2004, Steve Tell wrote:

> - Can g-wrap help with the C destructor problem, preventing future
> unwrapping of the C pointer that was wrapped at the call to the
> constructor?  (Its important in this case to be able to explicitly
> close objects created with the library, because they involve system
> resources (like open file descriptors) that may need to be returned at
> a particular time, instead of waiting for garbage collection.)  
> Or would I have to add another layer of indirection somehow?

GtkObjects have this problem, because of the gtk_object_destroy
procedure. It effectively does as you say, nulling out the pointer after
unreffing, and the C part of the wrapper detects for a destroyed value,
which will throw an error if a destroyed value is used.

This is possible because NULL is a magic value for the GObject wrapper;
it claims to have a reference on an object, and you can't have a
reference on NULL. Whether this is possible for WCT instances is as yet
unspecified; is it useful to wrap NULL? I would guess not, although are
there any counter-examples of the usefulness of a typed NULL?

FWIW, the wrap-value-cg in (g-wrap guile) seems to explicitly return #f
for NULL values. So perhaps that's the intent.

> - Since in this case I have control over the library's source, I could
> modify it to have seperate "close" and "free" routines.  How would I
> connect the "free" routine to be called at GC time?  Based on the
> documentation, I would think I would subclass <gw-guile-wct> and
> provide a destruct-value-cg for it, but I can't seem to figure out how
> to do that.  I've tried:
> 
>       (define-class <gw:parport*> (<gw-guile-wct>))
>       (define-method (destruct-value-cg (t <gw:parport*>)
>                                   (value <gw-value>)
>                                   status-var)
>         (list "parport_free(" (var value) ");\n"))
> 
> but get "Unbound variable: <gw-guile-wct>" in the define-class.

Hm. The unbound variable warning would be because (g-wrap guile) doesn't
export the class. Perhaps that's an oversight, although in 1.3.4, WCT
types were not extensible. Andreas?

Regarding making a destroy-value-cg (s/destruct/destroy/ in 1.9.1), I
think that's the correct solution. However, the current (g-wrap guile)
doesn't pass a cleanup function to gw_wct_new, so such a function will
never be called. However, the free function in guile-wct.c does free the
data. You should probably change (g-wrap guile) to somehow hook the
destroy-value function to the cleanup handler.

G-wrap makes my head hurt.

> - I might prefer that the guile wrapping of the library's "constructor"
> either return the wrapped-C-type object or throw an error, instead of
> returning #f for NULL pointers as it seems to do when using
> "wrap-as-wct!".  It looks like this might be doable by providing an
> alternate wrap-value-cg for this particular wrapped type; is this the 
> right approach?

The exception approach is correct, I think, but I don't know about
implementing it. Perhaps post-call-result-cg is what you want; see
(gnome gw glib-spec) for an example (although it uses post-call-arg-cg,
since GErrors are passed as arguments).

This code seems to be generally useful. Perhaps NULL should only be
allowed as a return value if (null-ok) is in the typespec options.
Otherwise it would throw an exception. Andreas?

> - I'd really like to have the guile version of this library construct and
> use goops objects, so I can inherit from and extend it.
> Do I have to wrap the C library into a module of non-goops guile procedures
> and then write a goops-using module that builds the objects and methods
> using the g-wrapped module?
> Or can g-wrap help in creating goops classes, objects and methods with 
> less intermediate glue required?
> 
> I suppose an alternate might be to rewrite the C library using gobject
> and get into guile-gnome-gobject.  While that's on my list of things
> to learn about, I might not want this little library's guile wrapping
> to depend on guile-gnome.

Well, on a base level, this could be possible. SMOB classes are given
GOOPS classes, which can allow you to make methods with SMOB types in
the arguments.

However, g-wrap needs some fixing, as noted in guile-wct.c near
gw_wct_create. In short, calling gw_wct_create should return a SMOB
class. Right now it creates a new SMOB, holding the type data, instead
of the SMOB class. This makes is-a? fail, IIRC.

If your needs go beyond the addition of methods, and *possibly*
inheritance (can't remember if this works or not), you should change the
library to be based around GObject. Otherwise, you will have to
reimplement a subset of guile-gobject, which is tricky. Trust me ;)

> Since the wrapped-C-pointer use of g-wrap isn't covered well in the g-wrap 
> documentation, figuring this out might serve as a useful example. (hint)

Good luck :-)

Cheers,
--
Andy Wingo <address@hidden>
http://ambient.2y.net/wingo/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]