GLUCOSCSH - Easy access to C from Scsh.


WHAT MODULE TO OPEN?

To make use of this package, you'll need to invoke scsh with -lel
glucoscsh/load.scm command line switch and open the "glue" structure.


THE SIMPLEST USE.

Suppose you want your scsh program to run as a daemon.  To this end
you want to call the daemon() function.  From the man page for daemon,
we see the interface it uses:

       #include <unistd.h>

       int daemon(int nochdir, int noclose);

As daemon() does not require us to load any dynamic libraries, we only
need to tell scheme about it's interface in order to have access to
the function from scheme.  To tell scheme about the daemon function,
use the c-function macro:

	(c-function i daemon i i)

This is a direct translation of the prototype for daemon() in C.  The
symbol "i" before the name of the function "daemon" tells scheme that
the function returns an integer.  The two following i's indicate that
the function accepts two arguments, both of which are integers.

You are now ready to call the function:

	(daemon 0 0)

That's it.  Note that the scheme versions of symbols with underscores
use underlines instead, so that if you would refer to the function
mysql_init() as mysql-init both when you call it and when you declare
it with the c-function macro.



WHAT HAPPENED?

When you call a function declared with the c-function macro the first
time, it may need to generate wrapper function called a glue function
that accepts the scheme object arguments, translates them to
appropriate C type objects, dispatches to the function we are calling,
and then translates the results back for use in scheme.  To this end,
it writes the glue function into a c file and then compiles and links
it into a shared library and then loads the library all before the
call can be made.  This can make for a large delay on the first call
to a c-function.  To avoid this, you may prefer to explicitly generate
all the glue for the program using the generate-glue call before you
use any of the c-functions:

	(generate-glue)


You may wonder where it puts all the glue files.  By default, it uses
the directory $HOME/.autoglue/cache.  Currently each user gets their
own glue cache.  In the future, a system-wide glue cache will be
supported.

You may want to override this default directory (for example, if you
are making bindings for some popular c library and want to keep the
glue for this project seperate from the glue cache in your home
directory so that you can distribute it or install it to a system-wide
glue cache).  To accomplish this, use the load-glue call before any
instances of the c-function macro:

	; Put glue in special mysql directory.
	(load-glue "./mysql-glue")
	


TYPE CODES.

Earlier, you saw that "i" stands for integer with regards to the
c-function macro.  The recognized type codes are:

	i  - integer (int)
	ui - unsigned integer (unsigned int)
	s  - string (char *)
	p  - pointer (void *)
	v  - void 
	sn - string or NULL (char *, may be NULL)

NULL pointers are mapped to the scheme value #f.


This may be inadequate for your needs.  To add new recognized type
codes, use the interfacing-rule macro.  For example, the type code "i"
might have been defined like this:

(interfacing-rule i
	"int"

	(extract macro EXTRACT_I "s48_extract_integer($1)")

	(enter macro ENTER_I "s48_enter_integer($1)")

	)

The first argument to the macro is the type code symbol we are
defining.  Then we specify the corresponding data type in C, here
"int".

The "extract" and "enter" clauses tell what code is neccessary to
extract the data from scheme into C, and to enter the data into scheme
from C.  The example above will cause the following macro definitions
to occur:

	#define EXTRACT_I(v) s48_extract_integer(v)
	#define ENTER_I(v) s48_enter_integer(v)

Note that the body of the macros are specified as strings and the
argument is denoted as $1 inside the strings.  You could opt to define
an inline function instead of a macro.  To do that, specify inline
instead of macro as the symbol immediately following the enter or
extract keyword.  In the case of an inline function, the string is the
body (just the body) of the function minus the surrounding braces.
Again use $1 as the argument.



EMBEDDING C CODE.

You may embed your own custom C functions in your scheme source using
the embedded-c macro.  For example, you might want to dereference a
pointer, copying its contents into a byte-vector:

(embedded-c (pointer-deref p (size ui) (index ui)) "
	    char *cp = S48_EXTRACT_VALUE(p,(char*));
	    return s48_enter_byte_vector( cp+index*size, size );
	    ")

This declares a function known in scheme as pointer-deref which takes
3 arguments: a pointer, a size multiplier, and an index into an array.
It returns the appropriate byte vector.  Notice that the argument
names are given first and then the types, for example (size ui) causes
the function header to declare "unsigned int size" in the generated C
file.  The argument p is not specified with a type.  This means that
it will be of type s48_value and will have to be converted to a C type
manually.  Functions declared in this way must return a value of the
type s48_value.



LINKING LIBRARIES.

In the example I presented at the top of this file, no dynamic library
needed to be explicitly linked.  This is not typically the case.  To
use a function that requires loading a shared library, use the
dynamic-load function provided with scheme48.  For example, to use the
crypt() function in scheme, you might add the following to the top of
your program:

	(dynamic-load "/usr/lib/libcrypt.so")

	(c-function s crypt s s)

Note that dynamic-load requires that you open the structure
dynamic-externals.
