Re: Missing GObject.connect function in typelib, but present in gir



Rotty,

Thank you for the explanation. Last night, I implemented it this way, too,
and it has worked without any problems. Hello World example is straight
forward, and easy to understand for gtk, pygtk and pygobject devs.

It is funny how both of us faced the same problem and had similar/same
solution for it.

Regards,
Marko Tasic


On Fri, Mar 25, 2011 at 2:54 PM, Andreas Rottmann <a rottmann gmx at> wrote:
Marko Tasic <mtasic85 gmail com> writes:

> Rotty,
>
> I took look at sbank, and I think it's more advance at this point than
> pygir-ctypes.
> Good job! However, I did it this way:
>
> * created new struct that extended GClosure called PyClosure
> * added notifiers for finalize and invalidate
> * instantiated PyClosure
> * connected with "hid = GObject.signal_connect_closure(window, 'destroy',
> closure, False)"
> * runned
>
> But, it fails with "Segmentation fault" on window close.
>
> Can you explain how you did this?
>
I didn't (anywhere in the code) mess with GClosure.  Here's what I did
for signal connection (see gobject/signals.sls for the full code):

- Manually pull out the relevant function from libgobject:

 (define-c-callouts libgobject
   (connect-data% 'ulong "g_signal_connect_data"
                  '(pointer pointer fpointer pointer fpointer int))
   [...])

- Then invoke the Scheme procedure bound to that function; passing it an
 appropriate callback-wrapper (a function pointer that calls back into
 Scheme, I guess Python's ctypes does have these as well):

 (define (g-signal-connect instance signal callback)
   (define (lose msg . irritants)
     (apply error 'g-signal-connect msg irritants))
   (let*-values
       (((signal detail detailed-signal) (parse-signal-spec signal lose))
        ((prepare) (gobject-class-get-signal-callback
                    (ginstance-class instance)
                    signal)))
     (unless prepare
       (lose "no such signal" detailed-signal))
     (receive (cb-ptr reclaim) (prepare callback)
       (let* ((detailed-signal-ptr (string->utf8z-ptr detailed-signal))
              (id (connect-data%
                   (ginstance-ptr instance)
                   detailed-signal-ptr
                   cb-ptr
                   (null-pointer)
                   (callback-destroy-notify reclaim)
                  0)))
         (free detailed-signal-ptr)
         id))))

 The notable things here are:

 - I pull a callback-wrapper creation procedure using
   `gobject-class-get-signal-callback' out of the class object
   associated with the instance in question, and bind it to `prepare'.
   The class object knows about the signals and their argument/return
   types, so it can produce that callback-wrapper generator procedure.

 - Call `prepare', getting a function pointer (`cb-ptr') and a
   procedure for reclaiming the callback (`reclaim').

 - Finally, invoke g_signal_connect_data() (aka connect-data%), passing
   the function pointer and a destroy notification function pointer
   that will call `reclaim'.

HTH, Rotty
--
Andreas Rottmann -- <http://rotty.yi.org/>



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