This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: How to create a new procedure type?


(nobody) writes:

> This question has gone unanswered for two days, and I, too, would like
> to know the answer.  From what I grasped of Guile's pre-1.3 dynamic
> loading support, callbacks could only take strings as args.  This
> seemed to me rather silly, since the actual arguments are of course
> going to be Scheme objects.  I guess you could sprintf(buf,"%ld",scm)
> but you'd probably outsmart the gc by doing it.
> 
> Is there any way to make a C function of type SCM (*)(int nargs, SCM*
> args) in a dynamically loaded module callable from Scheme?

First let me say that I'm not sure that I understand your question.

But I'll attempt an answer.  Sure there is!  I'll try to answer your
question in the context of one of the examples that appear in the
guile FAQ (http://idt.net/~mcmanus/guile-faq/guile-faq.html).  Here is
the example:

     /* $Id: hack.c,v 1.1 1999/04/14 21:18:02 mcmanr Exp $ */
     
     /* this code creates a new dynamically linkable module called (silly
        hack).  there is precisely one primitive defined in this module,
        '2+', which adds 2 to it's argument */
     
     #include <guile/gh.h>
     
     /* add new primitives here */
     SCM_PROC(s_2_plus, "2+", 1, 0, 0, scm_2_plus);
     static SCM
     scm_2_plus(SCM x)
     {
         SCM_ASSERT(gh_number_p(x), x, SCM_ARG1, s_2_plus);
         return(scm_sum(x, gh_int2scm(2)));
     }
     
     /* the init function */
     void
     scm_init_hack(void)
     {
     #   include "hack.x"
         return;
     }
     
     /* the pre-init function */
     void
     scm_init_silly_hack_module()
     {
         scm_register_module_xxx("silly hack", (void*)scm_init_hack);
     }


This is just about the smallest dynamically loadable C module
possible.  (You'll note that I'm not using gh_ functions, which is
probably a bug in the FAQ, but for now, I'm just creating example the
way I know how).

Take the SCM_PROC line.  It says that there is a new primitive
function named "2+" from scheme, whose C implementation is the
function scm_2_plus.  You can identify the c function in error
messages with the C constant string s_2_plus.

The numeric argument in position three represents the number of
required parameters.  The signature of scm_2_plus should start with
this many parameters of type SCM.  These parameters will always have
valid Scheme data when the runtime calls your function.

The numeric argument in position four represents the number of
optional parameters.  The signature of scm_2_plus should contain, in
addition to and following the parameters described previously, this
many parameters.  Each of these parameters may have the special value
SCM_UNDEFINED, depending on whether the user supplied the parameter.

The numeric argument in position five represents a C boolean
expression that specifies whether the function accepts a 'rest' list,
which corresponds to the dot notation in a lambda list.  I will try to
add an example of this functionality.  If the parameter is true (!= 0
in C parlance), then the signature for scm_2_plus should contain an
additional parameter, appearing at the end of the parameter list.
This final parameter will contain the user supplied list of additional
arguments to the C primitive, or SCM_EOL if no list was supplied.  So
this case is the one that I think will enable you to do what you want.

I think that there is a gh_ analog to all of this, which I need to
research and add to the FAQ.  If I'm totally off base about your
question, my regrets.

-russ


--
Death to all fanatics!