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: calling scheme function from C


Vadim Zaliva <lord@crocodile.org> writes:

> That is the best way to take pointer of some scheme function and call it
> from "C"? For example, I have following scheme definition:
> 
> (define (func str)
>  )
> 
> How can I call it from C? The one way I've found is use gh_eval_str(), but
> I have to prepare external representation of parameters.
> 
> I suspect there is way to take pointer to this function from C and simply
> call it.

I look up the the Scheme procedure by name each time I want to call it,
using 'scm_intern0' if the procedure is in the-root-module, or something
like this if it's in some other module (in this case 'guile-user'):

static SCM
make_callout(char *callout, SCM ls)
{
    SCM proc;
    char buf[512];
    sprintf(buf, "(module-ref (resolve-module '(guile-user)) '%s)", callout);
    proc = gh_eval_str(buf);
    if (proc == SCM_UNDEFINED) {
        printf("callout error: lookup failed for '%s'\n", callout);
        return SCM_UNDEFINED;
    } else {
        return scm_apply(proc, ls, SCM_EOL);
    }
}

To format arguments, I often use the convenience function
'scm_listify'.  Here is an example usage (note the SCM_UNDEFINED at
the end of the list):

int
ui_modify_verify_callout(UIRec *ui,
                         const char *widget_name,
                         const char *str,
                         int len,
                         char **ret_str)
{
    SCM obj;
    *ret_str = NULL;
    obj = make_callout("fte:modify-verify",
                       scm_listify(ui_box(ui),
                                   scm_makfrom0str(widget_name),
                                   scm_makfromstr(str, len, 0),
                                   SCM_UNDEFINED));
    if (SCM_NIMP(obj) && SCM_ROSTRINGP(obj)) {
        *ret_str = XtNewString(SCM_CHARS(obj));
    }
    return (obj == SCM_BOOL_F ? 0 : 1);
}

I understand that the CVS snapshots contain a C level interface to the
module system, so the jiggery-pokery above with gh_eval_str() should
be obsolete in the next release of guile.

I hope this helps,
-russ

--
WAR IS PEACE FREEDOM IS SLAVERY BACKSPACE IS DELETE