unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* dynamic ffi and C struct
@ 2012-05-19 11:32 cong gu
  2012-05-20  0:45 ` Mark H Weaver
  0 siblings, 1 reply; 3+ messages in thread
From: cong gu @ 2012-05-19 11:32 UTC (permalink / raw)
  To: guile-user

Hello,

Is it possible to use the current dynamic ffi to call a C function
whose parameter is a C struct (not a pointer to a C struct) ?

I cannot find much about it in the documentation.  After a brief look
at the source of foreign.c of guile, I found guile actually does some
parsing of nested argument list for `pointer->procedure' and generates
compound ffi types.  But I don't know the right data structure to give
when actually calling the foreign function.

For example, what should I do for the following function?

typedef struct {
  int dat[2];
} foo_t;

int func ( foo_t arg );

-- 
Cong Gu



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

* Re: dynamic ffi and C struct
  2012-05-19 11:32 dynamic ffi and C struct cong gu
@ 2012-05-20  0:45 ` Mark H Weaver
  2012-05-20  3:40   ` Nala Ginrut
  0 siblings, 1 reply; 3+ messages in thread
From: Mark H Weaver @ 2012-05-20  0:45 UTC (permalink / raw)
  To: cong gu; +Cc: guile-user

cong gu <gucong43216@gmail.com> writes:
> Is it possible to use the current dynamic ffi to call a C function
> whose parameter is a C struct (not a pointer to a C struct) ?

Although it is not documented in the manual, I see from the source code
that a C struct parameter can be specified using a nested list in the
foreign type passed to 'pointer->procedure'.

> For example, what should I do for the following function?
>
> typedef struct {
>   int dat[2];
> } foo_t;
>
> int func ( foo_t arg );

For this example, there's an additional complication of the inline array
within the struct, which is not supported by libffi, upon which Guile's
dynamic FFI is based.  I'm not an expert on this subject, but I strongly
suspect that on most (if not all) platforms, the struct above has the
same layout as the following one:

  typedef struct {
    int dat_0;
    int dat_1;
  } foo_t;

Assuming this is the case, here's one way to wrap 'func':

  (use-modules (system foreign))

  (define foo-library-obj (dynamic-link "libfoo"))
  (define foo-struct-type (list int int))
  
  (define (make-foo-struct dat-0 dat-1)
    (make-c-struct foo-struct-type (list dat-0 dat-1)))
  
  (define func
    (pointer->procedure int
                        (dynamic-func "func" foo-library-obj)
                        (list foo-struct-type)))

and here's an example of how to use it:

  (func (make-foo-struct 4 5))

It is also possible to wrap C functions that return structs, by passing
a list to the first parameter of 'pointer->procedure', and then using
'parse-c-struct' to extract the fields of the returned struct.

Hope this helps!

    Mark



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

* Re: dynamic ffi and C struct
  2012-05-20  0:45 ` Mark H Weaver
@ 2012-05-20  3:40   ` Nala Ginrut
  0 siblings, 0 replies; 3+ messages in thread
From: Nala Ginrut @ 2012-05-20  3:40 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user

And if you want to dereference the returned struct pointer, use parse-c-struct
say, there's a returned C struct like:
aa { (int)1 ,(int)2 }

you may convert it to list like this:
(parse-c-struct aa (list int int))
==> (1 2)

Then the rest is list operation, has no part in C.


On Sun, May 20, 2012 at 8:45 AM, Mark H Weaver <mhw@netris.org> wrote:
> cong gu <gucong43216@gmail.com> writes:
>> Is it possible to use the current dynamic ffi to call a C function
>> whose parameter is a C struct (not a pointer to a C struct) ?
>
> Although it is not documented in the manual, I see from the source code
> that a C struct parameter can be specified using a nested list in the
> foreign type passed to 'pointer->procedure'.
>
>> For example, what should I do for the following function?
>>
>> typedef struct {
>>   int dat[2];
>> } foo_t;
>>
>> int func ( foo_t arg );
>
> For this example, there's an additional complication of the inline array
> within the struct, which is not supported by libffi, upon which Guile's
> dynamic FFI is based.  I'm not an expert on this subject, but I strongly
> suspect that on most (if not all) platforms, the struct above has the
> same layout as the following one:
>
>  typedef struct {
>    int dat_0;
>    int dat_1;
>  } foo_t;
>
> Assuming this is the case, here's one way to wrap 'func':
>
>  (use-modules (system foreign))
>
>  (define foo-library-obj (dynamic-link "libfoo"))
>  (define foo-struct-type (list int int))
>
>  (define (make-foo-struct dat-0 dat-1)
>    (make-c-struct foo-struct-type (list dat-0 dat-1)))
>
>  (define func
>    (pointer->procedure int
>                        (dynamic-func "func" foo-library-obj)
>                        (list foo-struct-type)))
>
> and here's an example of how to use it:
>
>  (func (make-foo-struct 4 5))
>
> It is also possible to wrap C functions that return structs, by passing
> a list to the first parameter of 'pointer->procedure', and then using
> 'parse-c-struct' to extract the fields of the returned struct.
>
> Hope this helps!
>
>    Mark
>



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

end of thread, other threads:[~2012-05-20  3:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-19 11:32 dynamic ffi and C struct cong gu
2012-05-20  0:45 ` Mark H Weaver
2012-05-20  3:40   ` Nala Ginrut

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).