unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* C structures
@ 2005-12-30 13:11 Leonardo Lopes Pereira
  2005-12-30 15:04 ` Neil Jerram
  2005-12-30 15:58 ` Mike Gran
  0 siblings, 2 replies; 9+ messages in thread
From: Leonardo Lopes Pereira @ 2005-12-30 13:11 UTC (permalink / raw)


I would like to know if is there any way to convert C structs to any type of Guile data.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
  2005-12-30 13:11 C structures Leonardo Lopes Pereira
@ 2005-12-30 15:04 ` Neil Jerram
       [not found]   ` <20051230125804.f764063f.leonardolopespereira@gmail.com>
  2005-12-30 15:58 ` Mike Gran
  1 sibling, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2005-12-30 15:04 UTC (permalink / raw)
  Cc: guile-user

Leonardo Lopes Pereira <leonardolopespereira@gmail.com> writes:

> I would like to know if is there any way to convert C structs to any
> type of Guile data.

You need to be more precise about your requirements.  For example, at
the most basic level, we could say "yes, of course, the C structure

struct point {
  int x;
  int y;
}

can be converted to a Scheme pair: (cons x y)", but I'm guessing
that's not really what you meant.

Sorry, but please do write more.

       Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
  2005-12-30 13:11 C structures Leonardo Lopes Pereira
  2005-12-30 15:04 ` Neil Jerram
@ 2005-12-30 15:58 ` Mike Gran
  2005-12-30 16:19   ` Leonardo Lopes Pereira
  1 sibling, 1 reply; 9+ messages in thread
From: Mike Gran @ 2005-12-30 15:58 UTC (permalink / raw)


Leonardo-

A "list" can hold any type of data, so it shouldn't be a problem to
unpack a struct into a list.

There really isn't a way to automatically convert a C struct into a
list.  You'd have to convert each element of the struct into a Guile
type, then assemble them into a list.  

Converting a C struct to a list is a good idea if you're giving the C
data to Guile, and you won't need the C struct to be valid afterwards.

If you want Guile to operate on the C struct directly because it needs
to remain relevant, then a different approach is used.

Which of the following are you trying to accomplish?

1.  You want to make C data available to Guile functions, and once that
data is passed to Guile, it never (or rarely) needs to be handed back
to C.

2.  You want the C code and the Guile code to be able to operate on the
same C structs at the same time.

--
Mike Gran

--- Leonardo Lopes Pereira <leonardolopespereira@gmail.com> wrote:

> I would like to know if is there any way to convert C structs to any
> type of Guile data.
> 
> 



		
__________________________________________ 
Yahoo! DSL – Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com 



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
  2005-12-30 15:58 ` Mike Gran
@ 2005-12-30 16:19   ` Leonardo Lopes Pereira
  2005-12-30 17:01     ` Mike Gran
  2005-12-30 19:45     ` klaus schilling
  0 siblings, 2 replies; 9+ messages in thread
From: Leonardo Lopes Pereira @ 2005-12-30 16:19 UTC (permalink / raw)
  Cc: guile-user

Em Fri, 30 Dec 2005 07:58:30 -0800 (PST)
Mike Gran <spk121@yahoo.com> escreveu:

> Leonardo-
> 
> A "list" can hold any type of data, so it shouldn't be a problem to
> unpack a struct into a list.
> 
> There really isn't a way to automatically convert a C struct into a
> list.  You'd have to convert each element of the struct into a Guile
> type, then assemble them into a list.  
> 
> Converting a C struct to a list is a good idea if you're giving the
> C data to Guile, and you won't need the C struct to be valid
> afterwards.
> 
> If you want Guile to operate on the C struct directly because it
> needs to remain relevant, then a different approach is used.
This is what I want to do.
> 
> Which of the following are you trying to accomplish?
> 
> 1.  You want to make C data available to Guile functions, and once
> that data is passed to Guile, it never (or rarely) needs to be
> handed back to C.
No.
> 
> 2.  You want the C code and the Guile code to be able to operate on
> the same C structs at the same time.
Yes.


To be more clear. I want to be able to call a C function from guile.
The problem is that this function has a struct as an arg and this
struct has variable members. So, I need to create a list on
scheme/guile and convert it to a C struct that will be used as an arg
to that function.
> 
> --
> Mike Gran
> 
> --- Leonardo Lopes Pereira <leonardolopespereira@gmail.com> wrote:
> 
> > I would like to know if is there any way to convert C structs to
> > any type of Guile data.
> > 
> > 
> 
> 
> 
> 		
> __________________________________________ 
> Yahoo! DSL – Something to write home about. 
> Just $16.99/mo. or less. 
> dsl.yahoo.com 
> 


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
  2005-12-30 16:19   ` Leonardo Lopes Pereira
@ 2005-12-30 17:01     ` Mike Gran
  2005-12-30 19:45     ` klaus schilling
  1 sibling, 0 replies; 9+ messages in thread
From: Mike Gran @ 2005-12-30 17:01 UTC (permalink / raw)
  Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 965 bytes --]

Leonardo-

This isn't exactly what you what but, the code in the attached text
file shows how to declare a Guile function "c-func-wrap" takes a list
as an argument.  The function "c-func-wrap" converts that list into a
variable length C array of doubles which is passed to the C func
"c_func".

I just bashed it out, and haven't had a chance to test it.  It should
(almost) work, though.  There are probably prettier ways of
accomplishing this, as well.

--
Mike Gran

--- Leonardo Lopes Pereira <leonardolopespereira@gmail.com> wrote:

> To be more clear. I want to be able to call a C function from guile.
> The problem is that this function has a struct as an arg and this
> struct has variable members. So, I need to create a list on
> scheme/guile and convert it to a C struct that will be used as an arg
> to that function.


		
__________________________________________ 
Yahoo! DSL – Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com 

[-- Attachment #2: 1294945028-temp.c --]
[-- Type: application/octet-stream, Size: 1354 bytes --]

#include <stdio.h>
#include <string.h>

#include <libguile.h>

SCM scm_c_func_wrapper (SCM s_list);

int main(int argc, char **argv)
{

  /* initialize Guile */
  scm_init_guile();

  /* Register the new C-Guile functions */
  scm_c_define_gsubr 
    ("c-func-wrapper", 1, 0, 0, (SCM (*)()) scm_c_func_wrapper); 

  /* Call the Guile function */
  scm_c_eval_string("(c-func-wrapper '(1.0 2.0 3.0))");

  return 0;
}

SCM scm_c_func_wrapper (SCM s_list)
{
  SCM s_element;
  int length;
  int i;
  double *values;

  /* Check that the input is a list */
  SCM_ASSERT (SCM_NFALSEP (scm_list_p (s_list)), 
	      s_list, 
	      SCM_ARG1, 
	      "c-func-wrapper");
  length = scm_num2int(scm_length(s_list), 0, "scm_c_func_wrapper()");
     
  if (length == 0) {
    /* error? */
    return scm_double2num(0.0);
  } else {
    /* Allocate a C array to hold the values */ 
    values = (double *)malloc(sizeof(double) * length);
    
    /* Copy the Guile list into the C array */ 
    for (i=0; i < length; i++) {
      
      /* Get the i-th element of the list */ 
      s_value = scm_list_ref(s_list, scm_int2num(i));
      
      /* Convert it into a C double */
      values[i] = scm_num2double(s_value, 0, "main()");
    }
  }

  /* Call C func with variable length array that returns a double*/ 
  return scm_double2num(c_func(values, length));

}

[-- Attachment #3: Type: text/plain, Size: 140 bytes --]

_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user

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

* Re: C structures
  2005-12-30 16:19   ` Leonardo Lopes Pereira
  2005-12-30 17:01     ` Mike Gran
@ 2005-12-30 19:45     ` klaus schilling
  1 sibling, 0 replies; 9+ messages in thread
From: klaus schilling @ 2005-12-30 19:45 UTC (permalink / raw)
  Cc: guile-user, spikegran

Leonardo Lopes Pereira writes:
 > 
 > To be more clear. I want to be able to call a C function from guile.
 > The problem is that this function has a struct as an arg and this
 > struct has variable members. So, I need to create a list on
 > scheme/guile and convert it to a C struct that will be used as an arg
 > to that function.

one can add another smob type that actually holds a pointer to the struct.
this works well if the interface of the strcut is controlled by the C API.
Smobs also provide for garbage collection mechanism,
which is a problem in hand-woven conversions from structured C data to 
Scheme data. Most C libraries iontroducing struct arguments essentially
define the struct and functions to handle pointers of that struct,
including allocation functions , freeing functions, copying etc.
These need to be plugged into the definition of a smob type.
Jim Blandy wrote a manual for that almost 10 years ago,
coming with the guile dists.
Nowadays, the gh_ interface is deprecated, so one should
switch to scm_ interface in non-heritage projects

Klaus Schilling


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
       [not found]   ` <20051230125804.f764063f.leonardolopespereira@gmail.com>
@ 2005-12-31 13:14     ` Neil Jerram
  2005-12-31 16:00       ` Mike Gran
  0 siblings, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2005-12-31 13:14 UTC (permalink / raw)
  Cc: Guile Users

Leonardo,

Based on your replies to other people on the list, it sounds as though
you probably want a SMOB.  A SMOB is a way of passing a C pointer
(such as to an arbitrary struct) around opaquely in Scheme, and the
way to use them in quite well documented in a couple of places in the
Guile manual (1.7/CVS version): nodes "Defining New Types (Smobs)" and
"Dia Smobs".

In case something simpler would do, however, I've also added a few
comments below.

Leonardo Lopes Pereira <leonardolopespereira@gmail.com> writes:

> Let me give a example. I can pass some simple data...
>
> --- scheme.scm ---
> (define number 1)
>
> --- C program ---
> #include <stdio.c>
> #include <libguile.h>
> #include <guile/gh.h>
>
> int main ()
> {
>   int number
>   SCM s_symbol, s_value;
>   scm_init_guile ();
>
>   scm_c_primitive_load ("scheme.scm");
>   
>   s_symbol = scm_c_lookup("number");
>   s_value = scm_variable_ref(s_symbol);
>   number = gh_scm2int(s_value, 0, "main");
> }
>
> ---
>
> This convert the Scheme data in C data, but I do not know how to pass
> a group of data together. ex.: How to convert a (cons x y) into a
> struct?

Well, for example:

(define number (cons 3 4))

instead of (define number 1), and then

  struct point number
  SCM s_symbol, s_value;
  scm_init_guile ();

  scm_c_primitive_load ("scheme.scm");
  
  s_symbol = scm_c_lookup("number");
  s_value = scm_variable_ref(s_symbol);
  number.x = gh_scm2int(SCM_CAR(s_value), 0, "main");
  number.y = gh_scm2int(SCM_CDR(s_value), 0, "main");

instead of the C code above.  Does that make sense?

A scheme list can be as long as you like, so can hold more than 2
values, and each value can be a different type.  So you can equally
well have 2 numbers and a string, for example.

>
> I want to create a wrap to a function that has a sruct as arg, so, I
> need to create that struct in scheme and convert it to C, how to do
> that?

It depends what the C code expects as regards the lifetime of the
struct.  If the struct only needs to be value for the duration of the
call to your C func, you can allocate it on the stack, initialize it
from a Scheme pair/list as shown above, and then call the C func.  If
the struct needs to be longer lived than that, the SMOB approach is
probably best.

Regards,
        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
  2005-12-31 13:14     ` Neil Jerram
@ 2005-12-31 16:00       ` Mike Gran
  0 siblings, 0 replies; 9+ messages in thread
From: Mike Gran @ 2005-12-31 16:00 UTC (permalink / raw)
  Cc: Guile Users

Yeah.  There's a bit of overhead in getting a SMOB set up, but, it has
the advantage that you aren't keeping duplicate copies (a C copy and a
Scheme copy) of your information in memory.

--- Neil Jerram <neil@ossau.uklinux.net> wrote:

> Leonardo,
> 
> Based on your replies to other people on the list, it sounds as
> though
> you probably want a SMOB.  A SMOB is a way of passing a C pointer
> (such as to an arbitrary struct) around opaquely in Scheme, and the
> way to use them in quite well documented in a couple of places in the
> Guile manual (1.7/CVS version): nodes "Defining New Types (Smobs)"
> and
> "Dia Smobs".
> 
> In case something simpler would do, however, I've also added a few
> comments below.
> 
> Leonardo Lopes Pereira <leonardolopespereira@gmail.com> writes:
> 
> > Let me give a example. I can pass some simple data...
> >
> > --- scheme.scm ---
> > (define number 1)
> >
> > --- C program ---
> > #include <stdio.c>
> > #include <libguile.h>
> > #include <guile/gh.h>
> >
> > int main ()
> > {
> >   int number
> >   SCM s_symbol, s_value;
> >   scm_init_guile ();
> >
> >   scm_c_primitive_load ("scheme.scm");
> >   
> >   s_symbol = scm_c_lookup("number");
> >   s_value = scm_variable_ref(s_symbol);
> >   number = gh_scm2int(s_value, 0, "main");
> > }
> >
> > ---
> >
> > This convert the Scheme data in C data, but I do not know how to
> pass
> > a group of data together. ex.: How to convert a (cons x y) into a
> > struct?
> 
> Well, for example:
> 
> (define number (cons 3 4))
> 
> instead of (define number 1), and then
> 
>   struct point number
>   SCM s_symbol, s_value;
>   scm_init_guile ();
> 
>   scm_c_primitive_load ("scheme.scm");
>   
>   s_symbol = scm_c_lookup("number");
>   s_value = scm_variable_ref(s_symbol);
>   number.x = gh_scm2int(SCM_CAR(s_value), 0, "main");
>   number.y = gh_scm2int(SCM_CDR(s_value), 0, "main");
> 
> instead of the C code above.  Does that make sense?
> 
> A scheme list can be as long as you like, so can hold more than 2
> values, and each value can be a different type.  So you can equally
> well have 2 numbers and a string, for example.
> 
> >
> > I want to create a wrap to a function that has a sruct as arg, so,
> I
> > need to create that struct in scheme and convert it to C, how to do
> > that?
> 
> It depends what the C code expects as regards the lifetime of the
> struct.  If the struct only needs to be value for the duration of the
> call to your C func, you can allocate it on the stack, initialize it
> from a Scheme pair/list as shown above, and then call the C func.  If
> the struct needs to be longer lived than that, the SMOB approach is
> probably best.
> 
> Regards,
>         Neil
> 
> 
> 
> _______________________________________________
> Guile-user mailing list
> Guile-user@gnu.org
> http://lists.gnu.org/mailman/listinfo/guile-user
> 



	
		
__________________________________ 
Yahoo! for Good - Make a difference this year. 
http://brand.yahoo.com/cybergivingweek2005/


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

* Re: C structures
       [not found] <E1EsL1F-0006hc-Lg@pat.uio.no>
@ 2006-01-04 21:10 ` Kjetil S. Matheussen
  0 siblings, 0 replies; 9+ messages in thread
From: Kjetil S. Matheussen @ 2006-01-04 21:10 UTC (permalink / raw)



Leonardo Lopes Pereira:
>
> I would like to know if is there any way to convert C structs to any type of Guile data.
>

SND has some neat features for doing that:
http://ccrma.stanford.edu/software/snd/

Example:

(load-from-path "eval-c.scm")
#<unspecified>

(define-ec-struct <test>
   <int> data
   <int-*> datas
   <something-else-*> somethingelse)
#<unspecified>

(define test (<test> #:data 1
 		     #:datas '(2 3 4)))
#<unspecified>

(-> test data)
1

(-> test data 5)
#<unspecified>

(-> test data)
5

(-> test datas)
(2 3 4)

(-> test datas '(9 2 3 4))
#<unspecified>

(-> test datas)
(9 2 3 4)

I think there are direct support for chars, floats, ints, floats, doubles, 
strings and SCMs. Everything else is treated as pointers.



-- 


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


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

end of thread, other threads:[~2006-01-04 21:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-30 13:11 C structures Leonardo Lopes Pereira
2005-12-30 15:04 ` Neil Jerram
     [not found]   ` <20051230125804.f764063f.leonardolopespereira@gmail.com>
2005-12-31 13:14     ` Neil Jerram
2005-12-31 16:00       ` Mike Gran
2005-12-30 15:58 ` Mike Gran
2005-12-30 16:19   ` Leonardo Lopes Pereira
2005-12-30 17:01     ` Mike Gran
2005-12-30 19:45     ` klaus schilling
     [not found] <E1EsL1F-0006hc-Lg@pat.uio.no>
2006-01-04 21:10 ` Kjetil S. Matheussen

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