Quote:
> > Is anybody doing cgi style web programming in scheme?
> > Is there any scheme module for apache?
> This is difficult to do, at least with the Scheme environments I
> looked at (Guile, SCM and a few others), because they don't play nice
> with the top level C environment. They want you to call a function
> that never returns to do processing of Scheme. Ick.
Gambit-C supports this. Basically the C world calls a function to
initialize the Scheme side of the application, and this function
returns control normally to the C world. Then from C you can call all
Scheme functions that have been exported to the C world (using the
c-define special form of the C-interface). There is an example of
this in the Gambit-C distribution, below is the C and Scheme code.
Marc
/* File: "client.c" */
#include <stdio.h>
#include <stdlib.h>
/*
* ___VERSION must match the version number of the Gambit header file.
*/
#define ___VERSION 21
#include "gambit.h"
/*
* Include declarations exported by server.
*/
#include "server.h"
/*
* Define SCHEME_LIBRARY_LINKER as the name of the Scheme library
* prefixed with "____20_" and suffixed with "__". This is the
* function that initializes the Scheme library.
*/
#define SCHEME_LIBRARY_LINKER ____20_server__
extern ___mod_or_lnk SCHEME_LIBRARY_LINKER ();
int main (argc, argv)
int argc;
char **argv;
{
char *temp;
/*
* Setup the Scheme library by calling "___setup" with appropriate
* parameters. The parameters set to zero will use the system
* default.
*/
___setup_params_struct setup_params;
setup_params.argc = argc;
setup_params.argv = argv;
setup_params.stack_cache = 0;
setup_params.min_heap = 0;
setup_params.max_heap = 0;
setup_params.live_percent = 0;
setup_params.gc_hook = 0;
setup_params.fatal_error = 0;
setup_params.standard = 0;
setup_params.debug_level = 0;
setup_params.default_io_encoding = ___IO_CHAR_ENCODING; /* native encoding */
setup_params.force_tty = 0;
setup_params.force_unbuffered_io = 0;
setup_params.linker = SCHEME_LIBRARY_LINKER;
___setup (&setup_params);
/* Main part of program: call Scheme functions */
temp = eval_string ("(define x 200)");
if (temp != 0)
{
printf ("result = %s\n", temp);
___free_string (temp); /* don't forget to reclaim string */
}
temp = eval_string ("(expt 2 x)");
if (temp != 0)
{
printf ("result = %s\n", temp);
___free_string (temp);
}
temp = eval_string ("(+ 1 2"); /* note: missing closing parenthesis */
if (temp != 0)
{
printf ("result = %s\n", temp);
___free_string (temp);
}
temp = eval_string ("(+ x y)"); /* note: y is unbound */
if (temp != 0)
{
printf ("result = %s\n", temp);
___free_string (temp);
}
/* Cleanup the Scheme library (required before terminating) */
___cleanup ();
/* Terminate program */
exit (0);
Quote:
}
/* File: "server.h" */
/*
* The only declaration in "server.scm" is the function "eval_string".
*/
extern char *eval_string ( /* char* */ );
; file: "server.scm", 11/10/96
; This file shows how to use the C-interface to implement a "Scheme
; server", that is a program which is mainly written in C and that
; makes calls to Scheme functions to access certain services.
;------------------------------------------------------------------------------
; This is a simple server that can evaluate a string of Scheme code.
(define (catch-all-errors thunk)
(call-with-current-continuation
(lambda (return)
(##catch-all
(lambda (signal-name args)
(return
(if (symbol? signal-name) (symbol->string signal-name) #f)))
thunk))))
(define (read-from-string str)
(with-input-from-string str read))
(define (write-to-string obj)
(with-output-to-string (lambda () (write obj))))
; The following "c-define" form will define the function "eval_string"
; which can be called from C just like an ordinary C function. The
; single argument is a character string (C type "char*") and the
; result is also a character string.
(c-define (eval-string str) (char-string) char-string "eval_string" "extern"
(catch-all-errors
(lambda () (write-to-string (eval (read-from-string str))))))
;------------------------------------------------------------------------------