unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* FFI questions
@ 2020-05-15 13:47 Jan Synacek
  2020-05-15 20:09 ` Taylan Kammer
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Synacek @ 2020-05-15 13:47 UTC (permalink / raw)
  To: guile-user

Hello,

Currently I have something like this:

(define libxcb (dynamic-link "libxcb"))

...

(define c-change-window-attributes
  (pointer->procedure void
     (dynamic-func "xcb_change_window_attributes" libxcb)
     (list '* uint32 uint32 '*)))

(define (change-window-attributes conn win mask vals)
   (c-change-window-attributes conn win mask (bytevector->pointer vals)))

The last argument to xcb_change_window_attributes is 'const void *' and I
need to pass a u32 vector to it. As it is right now, it segfaults when I
try passing #u32(something) to 'change-window-attributes'. Is it possible
to make it accept a u32 vector using just Scheme or do I have to work
around it on the C level?


My second question is about FFI and structs. Is it possible to access C
struct members from Scheme by name? If not, how do I generally approach the
problem? I've checked how guile-xcb does it and it seems to be building
hash tables with field names as keys. But that basically requires me to
"redefine" all the C structs that I would be interested in at the Scheme
level.

Regards,
-- 
Jan Synacek
Software Engineer, Red Hat


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: FFI questions
  2020-05-15 13:47 FFI questions Jan Synacek
@ 2020-05-15 20:09 ` Taylan Kammer
  2020-05-15 23:52   ` Matt Wette
  2020-05-17 10:06   ` Jan Synacek
  0 siblings, 2 replies; 5+ messages in thread
From: Taylan Kammer @ 2020-05-15 20:09 UTC (permalink / raw)
  To: Jan Synacek, guile-user

On 15.05.2020 15:47, Jan Synacek wrote:
> Hello,
> 
> Currently I have something like this:
> 
> (define libxcb (dynamic-link "libxcb"))
> 
> ...
> 
> (define c-change-window-attributes
>    (pointer->procedure void
>       (dynamic-func "xcb_change_window_attributes" libxcb)
>       (list '* uint32 uint32 '*)))
> 
> (define (change-window-attributes conn win mask vals)
>     (c-change-window-attributes conn win mask (bytevector->pointer vals)))
> 
> The last argument to xcb_change_window_attributes is 'const void *' and I
> need to pass a u32 vector to it. As it is right now, it segfaults when I
> try passing #u32(something) to 'change-window-attributes'. Is it possible
> to make it accept a u32 vector using just Scheme or do I have to work
> around it on the C level?

I think the reason it segfaults might be that the #u32() object gets 
garbage collected soon after you call bytevector->pointer on it.  See 
that you put it in a variable, and reference that variable at some point 
after xcb_change_windor_attributes should be done with the vector, to 
make sure that this is not the problem.

Otherwise I'm not sure why it should segfault.  A #u32() bytevector 
really should be backed by a contiguous array of uint32_t values, just 
like what you'll get when you define a uint32_t[] in C.

> My second question is about FFI and structs. Is it possible to access C
> struct members from Scheme by name? If not, how do I generally approach the
> problem? I've checked how guile-xcb does it and it seems to be building
> hash tables with field names as keys. But that basically requires me to
> "redefine" all the C structs that I would be interested in at the Scheme
> level.

These might be useful:

https://github.com/TaylanUB/scheme-bytestructures

https://www.nongnu.org/nyacc/ffi-help.html

I maintain bytestructures, am happy to answer questions.  (If I don't 
respond on the mailing list, feel free to mail me directly or open an 
issue on GitHub; mails with guile-user@gnu.org and guile-devel@gnu.org 
in the To: or Cc: fields land in a folder that I don't always check.)

The FFI Helper is by Matt Wette who also hangs around on this mailing 
list I believe.


- Taylan



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: FFI questions
  2020-05-15 20:09 ` Taylan Kammer
@ 2020-05-15 23:52   ` Matt Wette
  2020-05-15 23:59     ` Matt Wette
  2020-05-17 10:06   ` Jan Synacek
  1 sibling, 1 reply; 5+ messages in thread
From: Matt Wette @ 2020-05-15 23:52 UTC (permalink / raw)
  To: guile-user

On 5/15/20 1:09 PM, Taylan Kammer wrote:
>
> The FFI Helper is by Matt Wette who also hangs around on this mailing 
> list I believe.
>

I think Taylan's suggestion on your first part is probably correct.
Bytestructures allows you to access and change structure members by name.

Matt



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: FFI questions
  2020-05-15 23:52   ` Matt Wette
@ 2020-05-15 23:59     ` Matt Wette
  0 siblings, 0 replies; 5+ messages in thread
From: Matt Wette @ 2020-05-15 23:59 UTC (permalink / raw)
  To: guile-user



On 5/15/20 4:52 PM, Matt Wette wrote:
> On 5/15/20 1:09 PM, Taylan Kammer wrote:
>>
>> The FFI Helper is by Matt Wette who also hangs around on this mailing 
>> list I believe.
>>
>
> I think Taylan's suggestion on your first part is probably correct.
> Bytestructures allows you to access and change structure members by name.
>
> Matt
>
And by the way, the FFI Helper has a "x11-xcb.ffi" file included.
Here is the code generated for your procedure:
(My converter says this returns int not void, btw.)

;; xcb_void_cookie_t xcb_change_window_attributes(xcb_connection_t *c,
;;     xcb_window_t window, uint32_t value_mask, const void *value_list);
(define xcb_change_window_attributes
   (let ((~xcb_change_window_attributes
           (delay (fh-link-proc
                    (list ffi:unsigned-int)
                    "xcb_change_window_attributes"
                    (list ffi-void* ffi:uint32 ffi:uint32 ffi-void*)
                    ffi-x11-xcb-llibs))))
     (lambda (c window value_mask value_list)
       (let ((~c ((fht-unwrap xcb_connection_t*) c))
             (~window (unwrap~fixed window))
             (~value_mask (unwrap~fixed value_mask))
             (~value_list (unwrap~pointer value_list)))
         ((fht-wrap xcb_void_cookie_t)
          ((force ~xcb_change_window_attributes)
           ~c
           ~window
           ~value_mask
           ~value_list))))))




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: FFI questions
  2020-05-15 20:09 ` Taylan Kammer
  2020-05-15 23:52   ` Matt Wette
@ 2020-05-17 10:06   ` Jan Synacek
  1 sibling, 0 replies; 5+ messages in thread
From: Jan Synacek @ 2020-05-17 10:06 UTC (permalink / raw)
  To: Taylan Kammer; +Cc: guile-user

On Fri, May 15, 2020 at 10:09 PM Taylan Kammer <taylan.kammer@gmail.com> wrote:
>
> On 15.05.2020 15:47, Jan Synacek wrote:
> > Hello,
> >
> > Currently I have something like this:
> >
> > (define libxcb (dynamic-link "libxcb"))
> >
> > ...
> >
> > (define c-change-window-attributes
> >    (pointer->procedure void
> >       (dynamic-func "xcb_change_window_attributes" libxcb)
> >       (list '* uint32 uint32 '*)))
> >
> > (define (change-window-attributes conn win mask vals)
> >     (c-change-window-attributes conn win mask (bytevector->pointer vals)))
> >
> > The last argument to xcb_change_window_attributes is 'const void *' and I
> > need to pass a u32 vector to it. As it is right now, it segfaults when I
> > try passing #u32(something) to 'change-window-attributes'. Is it possible
> > to make it accept a u32 vector using just Scheme or do I have to work
> > around it on the C level?
>
> I think the reason it segfaults might be that the #u32() object gets
> garbage collected soon after you call bytevector->pointer on it.  See
> that you put it in a variable, and reference that variable at some point
> after xcb_change_windor_attributes should be done with the vector, to
> make sure that this is not the problem.
>
> Otherwise I'm not sure why it should segfault.  A #u32() bytevector
> really should be backed by a contiguous array of uint32_t values, just
> like what you'll get when you define a uint32_t[] in C.

This works, thanks!

(define (change-window-attributes conn win mask vals)
  (define b (list->u32vector vals))
  (c-xcb-change-window-attributes conn win mask (bytevector->pointer b)))

> > My second question is about FFI and structs. Is it possible to access C
> > struct members from Scheme by name? If not, how do I generally approach the
> > problem? I've checked how guile-xcb does it and it seems to be building
> > hash tables with field names as keys. But that basically requires me to
> > "redefine" all the C structs that I would be interested in at the Scheme
> > level.
>
> These might be useful:
>
> https://github.com/TaylanUB/scheme-bytestructures
>
> https://www.nongnu.org/nyacc/ffi-help.html
>
> I maintain bytestructures, am happy to answer questions.  (If I don't
> respond on the mailing list, feel free to mail me directly or open an
> issue on GitHub; mails with guile-user@gnu.org and guile-devel@gnu.org
> in the To: or Cc: fields land in a folder that I don't always check.)

Very interesting, I'll take a look.

Thank you,
-- 
Jan Synacek
Software Engineer, Red Hat




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-05-17 10:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-15 13:47 FFI questions Jan Synacek
2020-05-15 20:09 ` Taylan Kammer
2020-05-15 23:52   ` Matt Wette
2020-05-15 23:59     ` Matt Wette
2020-05-17 10:06   ` Jan Synacek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).