| How to extend C programs with Guile | ||
|---|---|---|
| <<< Previous | Data and Values | Next >>> |
Creating non-aggregate Guile variables from C is straightforward. A C value, such as an int, is converted into an SCM, and then the function scm_c_define is used to create a Guile variable from that SCM.
As a demonstration of the process, a small program is presented. It has a similar structure to the hello_world example, consisting of a main.c, a scheme script, and a makefile.
Example 1. c_num_2_guile: main.c
#include <stdio.h>
#include <stdlib.h>
#include <libguile.h>
int main()
{
/* Start up the Guile interpeter */
scm_init_guile();
/* Define some Guile variables from C */
scm_c_define("my-age", scm_int2num(32));
scm_c_define("my-height", scm_long2num(184));
scm_c_define("my-weight", scm_double2num(170.0));
/* Run a script that prints out the variables */
scm_c_primitive_load("script.scm");
return(EXIT_SUCCESS);
}
|
Example 2. c_num_2_guile: script.scm
(display "my-age --> ")
(display my-age)
(newline)
(display "my-height --> ")
(display my-height)
(newline)
(display "my-weight --> ")
(display my-weight)
(newline)
|
Example 3. c_num_2_guile: makefile
CDEBUG = -g -Wall
CFLAGS = $(CDEBUG) $(CDEFS) `guile-config compile`
LDFLAGS = `guile-config link`
SRCS = main.c
OBJS = main.o
c_num_2_guile: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
|
In the example program, the main.c defines some Guile variables and then executes the Guile file script.scm. The file script.scm contains the code to print out the variables, demonstrating that they've been properly created as Guile top-level variables.
When the program is run, it outputs the following:
my-age --> 32
my-height --> 184
my-weight --> 170.0
|
In the first function definition in main.c, the function scm_int2num takes a C integer, and converts it into an SCM. This SCM is passed directly into the function scm_c_define, where a Guile variable by the name of my-age containing the SCM data is created.
The function scm_int2num is just one of a family of C-to-SCM conversion functions. The rest of the important functions in this family are now described.
To convert a C type to Guile boolean, there is the macro SCM_BOOL.
SCM_BOOL converts a C value of any type into a Guile bool. Any C value that evaluates to zero will return #f. Otherwise it returns #t.
To convert a C int or char into a Guile char, there is the macro SCM_MAKE_CHAR.
![]() | Since Guile chars are unsigned, C chars should be cast to unsigned before conversion. For more on the problems that might occur if this isn't done, see the code in Example 4 in the section called Converting to C signed char or unsigned char> and the output in Example 5 in the section called Converting to C signed char or unsigned char>. |
SCM_MAKE_CHAR converts a C char or int of any type into a Guile char
The functions that convert C integers into SCMs include the following.
SCM scm_short2num(short n);
SCM scm_ushort2num(unsigned short n);
SCM scm_int2num(int n);
SCM scm_uint2num(unsigned int n);
SCM scm_long2num(long n);
SCM scm_ulong2num(unsigned long n);
SCM scm_long_long2num(long long sl);
SCM scm_ulong_long2num(unsigned long long sl);
All of these functions behave in the same way. They take the C number and see if it is small enough to fit into an inum. They check the value, not the type. Some C long numbers will be small enough to fit into an inum, and some will not.
If the number is too large for an inum, it gets converted into a bignum.
It is possible to compile libguile with bignum support disactivated. If this is the case, a number too large for an inum gets converted into a real.
The following two functions convert special C integer types into SCMs.
The function scm_size2num takes a C size_t as input, and the function scm_ptrdiff2num take a C ptrdiff_t as input.
The actual conversion from C to Guile follows the same rules as the integer types.
The following two functions convert C floating-point types into SCMs.
Both of these functions take the C value and convert it into a real.
There is no Guile function that converts C long double numbers because they are larger than the Guile real type.
There is one function to create a complex type.
The function scm_make_complex, given two C doubles, returns a Guile complex. If the imaginary part y is zero, it returns a Guile real value.
Since a Guile string can contain characters of value (char)0 while a C string cannot, Guile strings can contain arbitrary 8-bit binary data. Guile strings are sometimes used for this, making string conversion is not quite so straight-forward as numerical conversion.
For all the functions below, it is important to note that Guile has a maximum string length of 224 or 16 MB.
The conversion of a standard zero-terminated C string into a Guile string is by using either of scm_makfrom0str or scm_take0str.
The function scm_makfrom0str creates a Guile string from a C string. One will end up with two copies of the same string in memory, the C version and the Guile version.
The function scm_take0str passes the pointer for a C string and makes an SCM that contains that pointer. Thus the string isn't copied (a deep copy). Only its address is copied (a shallow copy). This has the advantage of avoiding duplication of strings in memory, but, it places burdens on what the C code may do with the string. First, the C code must have allocated the string using malloc. Second, the C code must never free the string. Also, undefined things may happen if the C code modifies the string after a SCM is made from it. Causing the string to grow or shrink would definitely cause problems. Also, Guile may free the string if it isn't being used any more.
Because a Guile string can contain arbitrary 8-bit data that is not zero-terminated, there are two analogous functions for operating on generic binary data.
These functions both take two arguments, instead of one. The first argument is the pointer to the block of memory. The second argument is the length of the block in bytes.
These scm_mem2string creates an SCM from a copy of a block of arbitrary 8-bit data of length len. The data is deep copied so that a new copy of the string exists in memory.
These scm_take_str creates an SCM from a copy of a block of arbitrary 8-bit data of length len. The data is shallow copied so that the SCM is a pointer that points to the memory location of the C 8-bit data.
![]() | scm_take_str requires that the last byte in its block be zero, so make sure to set
|
The function scm_istring2number converts a C string of length len that contains a number into a Guile number.
The many conversion routines listed previously create SCM variables. To the take the next step of creating Guile top-level variables from SCM, the following function is the most direct route.
The function scm_c_define Create a top-level Guile variable with the name name and the value val.
The use of this function is demonstrated in Example 1 in the section called Creating Guile Top-Level Variables from C>.
| <<< Previous | Home | Next >>> |
| Data and Values | Up | Reading Guile Top-Level Variables into C |