This SRFI is currently in withdrawn status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-50@nospamsrfi.schemers.org
. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI describes an interface for calling C functions from Scheme, calling Scheme functions from C, and allocating storage in the Scheme heap. Scheme manages stub functions in C that negotiate between the calling conventions of Scheme and C and the memory allocation policies of both worlds.
The following facilities are available for interfacing between Scheme and C:
The interface is closely based on that of Scheme 48 and scsh.
SCHEME_EXTRACT_STRING
Is it always possible to implement SCHEME_EXTRACT_STRING
in the manner described? SCHEME_EXTRACT_STRING
assumes that it is always possible to return a pointer to the contents of the string. Exactly how that contents might be organized is another issue. It may not be possible to use the contents of the string in an implementation-independent fashion. Efficient portable access to the contents of strings is a difficult issue.
This draft does not address the string/character encoding issue at all. Worse, it probably prescribes something that is incompatible with using Unicode or some other wide representation of characters. We don't know enough about the issues involved to speculate on how they should be addressed. They definitely should be addressed, however.
Signals might occur during the execution of C code. Since Scheme implementations often manage signals themselves, it is not clear how to specify what happens during such an event. This aspect of the C interface is probably best left unspecified.
For some Scheme implementations, it may be possible to implement calls from Scheme to C in a significantly cheaper manner if callbacks from C into Scheme are forbidden. Should there be separate versions of call-imported-c-binding
and call-imported-n-ary-c-binding
forbidding callbacks?
More examples will be added once the design has settled down.
The goal of this SRFI is to facilitate interfacing C libraries with a wide variety of Scheme implementations.To this end, the following criteria were considered in the design of the interface.
Scheme implementations supporting this SRFI should also support SRFI 9 ("Defining Record Types").
The names of all of Scheme's visible C bindings begin with `scheme_
' (for functions and types) or `SCHEME_
' (for macros). Whenever a C name is derived from a Scheme identifier, we replace `-
' with `_
' and convert letters to lowercase for functions and uppercase for macros. A final `?
' converted to `_p
' (`_P
' in C macro names). A final `!
' is dropped. Thus the C macro for Scheme's pair?
is SCHEME_PAIR_P
and the one for set-car!
is SCHEME_SET_CAR
. Functions and macros that do not check the types of their arguments have `unsafe
' in their names.
All of the C functions and macros described have prototypes or definitions in the header file srfi-50.h
which can be included via
#include "srfi-50.h"The C type for Scheme values is defined there to be
scheme_value
.Note that most functionality on the C side is implemented by macros.
When the type of a value is known, such as the integer returned by vector-length
or the boolean returned by pair?
, the corresponding C procedure returns a C value of the appropriate type, and not a scheme_value
.
The Scheme system may use a copying garbage collector. The collector must be able to locate all references to objects allocated in the Scheme heap in order to ensure that storage is not reclaimed prematurely and to update references to objects moved by the collector. The garbage collector may run whenever an object is allocated in the heap. C variables whose values are Scheme objects and which are live across heap allocation calls need to be registered with the garbage collector.
Shared bindings are the means by which named values are shared between Scheme code and C code. There are two separate tables of shared bindings, one for values defined in Scheme and accessed from C and the other for values going the other way. Shared bindings actually bind names to cells, to allow a name to be looked up before it has been assigned. This is necessary because C initialization code may be run before or after Scheme initialization code, where one accesses shared bindings created by the other, depending on implementation details of the underlying Scheme system.
(define-exported-c-binding
name value)
scheme_value SCHEME_GET_IMPORTED_BINDING(char *name)
(may GC)scheme_value SCHEME_SHARED_BINDING_REF(scheme_value shared_binding)
Define-exported-c-binding
makes value available to C code under as name which must be a string , creating a new shared binding if necessary.
The C macro SCHEME_GET_IMPORTED_BINDING
returns the shared binding defined for name
, again creating it if necessary.
The C macro SCHEME_SHARED_BINDING_REF
dereferences a shared binding, returning its current value.
The value of a shared binding that has not been defined is undefined.
void SCHEME_DEFINE_EXPORTED_BINDING(char *name, scheme_value v)
(may GC)(get-imported-c-binding
string)
(shared-c-binding-ref
shared-c-binding)
These are used to define shared bindings from C and to access them from Scheme. Again, if a name is looked up before it has been defined, a new binding is created for it.
void SCHEME_EXPORT_FUNCTION(name)
This macro covers the common case of exporting a C function to Scheme. SCHEME_EXPORT_FUNCTION(name)
expands into
scheme_define_exported_binding("name", scheme_enter_pointer(name))
which boxes the function into a Scheme object and then exports it. Note that scheme_enter_pointer
allocates space in the Scheme heap and might trigger a garbage collection.
(import-definition
<name>)
(syntax)(import-definition
<name> <c-name>)
(syntax)These macros simplify importing definitions from C to Scheme. They expand into
(define <name> (get-imported-c-binding <c-name>
))
where <c-name> is as supplied for the second form. For the first form <c-name> is derived from <name> by replacing `-
' with `_
' and converting letters to lowercase. For example, (import-definition my-foo)
expands into
(define my-foo (lookup-imported-c-binding "my_foo"))
It is expected that a piece of C code that provides functions callable from Scheme provide an initialization function that creates exported bindings for these functions. The mechanism by which the Scheme system calls this initialization function is implementation-dependent.
There are a number of other Scheme procedures and C functions related to shared bindings.
Scheme predicates return #t
for true and #f
for false. C predicates return a non-zero value for true and 0 for false.
(shared-c-binding?
obj)
int SCHEME_SHARED_BINDING_P(x)
Shared-c-binding?
and SCHEME_SHARED_BINDING_P
are predicates for shared bindings.
(shared-c-binding-name
shared-c-binding)
scheme_value SCHEME_SHARED_BINDING_NAME(scheme_value s_b)
Shared-c-binding-name
and SCHEME_SHARED_BINDING_NAME
return the name of a binding as a Scheme string.
(shared-c-binding-is-import?
shared-c-binding)
int SCHEME_SHARED_BINDING_IS_IMPORT_P(scheme_value s_b)
Shared-c-binding-is-import?
returns #t
if the binding was defined from C, #f
otherwise.
SCHEME_SHARED_BINDING_IS_IMPORT_P
returns a non-zero value if the binding was defined from Scheme, 0 otherwise.
(shared-c-binding-set!
shared-c-binding obj)
void SCHEME_SHARED_BINDING_SET(scheme_value s_b, scheme_value v)
Shared-c-binding-set!
and SCHEME_SHARED_BINDING_SET
change the value of a binding.
(define-imported-c-binding
string obj)
(lookup-exported-c-binding
string)
Define-imported-c-binding
and lookup-exported-c-binding
are Scheme versions of scheme_define_exported_binding
and scheme_lookup_imported_binding
.
(undefine-imported-c-binding
string)
(undefine-exported-c-binding
string)
The two undefine-
procedures remove bindings from the two tables. They do nothing if the name is not found in the table.
(call-imported-c-binding
binding arg1 ...)
This applies its first argument, an imported binding containing a C function, to the rest of the arguments. Binding must be an imported binding that contains a C function pointer converted to a Scheme value via SCHEME_ENTER_POINTER
. The C function is passed the argi values and the value returned is that returned by C procedure. No automatic representation conversion occurs for either arguments or return values. Up to 12 arguments may be passed.
Note that the C function, if it allocates Scheme heap storage, must register its parameters with the garbage collector.
There is no method supplied for returning multiple values to Scheme from C (or vice versa) (mainly because C does not have multiple return values).
(call-imported-c-binding/variable-arity
binding arg1 ... argn)
This applies its first argument, an imported binding containing a C function to two arguments:
int
.scheme_value []
which contains the arguments arg1...
argn in that order.Upon entry into the C function, the Scheme objects contained in the array have already been registered with the garbage collector and are deregistered after the C function has returned.
The C function should not modify the contents of the array.
(import-lambda-definition
<name> (
<variable> ... )
)
(syntax)(import-lambda-definition
<name> (
<variable> ... )
<c-name>)
(syntax)These macros simplify importing functions from C. They define <name> to be a procedure with the given parameters that passes their values to the corresponding C binding.<C-name>, if supplied, should be a string. These expand into
(define <name> (let ((temp (lookup-imported-c-binding <c-name>))) (lambda (<variable> ...) (call-imported-c-binding temp <variable> ...)))
If <c-name> is not supplied, it is derived from <name> by converting all letters to lowercase and replacing `-
' with `_
'.
The following macros denote Scheme constants:
SCHEME_FALSE
#f
.SCHEME_TRUE
#t
.SCHEME_NULL
SCHEME_UNSPECIFIC
The following macros convert values between Scheme and C representations. The `EXTRACT' ones convert from Scheme to C and the `ENTER's go the other way.
All of the `EXTRACT' macros check their arguments. Upon a type (or range) mismatch, an error is signalled. (See Signalling errors from external code.)
int SCHEME_EXTRACT_BOOLEAN(scheme_value)
scheme_value SCHEME_ENTER_BOOLEAN(int)
SCHEME_EXTRACT_BOOLEAN
returns 0 if its argument is #f
and a non-zero value otherwise. SCHEME_ENTER_BOOLEAN
is #f
if its argument is zero and #t
otherwise.
SCHEME_ENTER_BOOLEAN
returns SCHEME_FALSE
if its argument is 0 and SCHEME_TRUE
otherwise:
char SCHEME_EXTRACT_CHAR(scheme_value)
scheme_value SCHEME_ENTER_CHAR(char)
(may GC)SCHEME_EXTRACT_CHAR
converts a Scheme character to a C char
value. SCHEME_ENTER_CHAR
performs the conversion in the opposite direction.
char * SCHEME_EXTRACT_STRING(scheme_value)
scheme_value SCHEME_ENTER_STRING(char *)
(may GC)SCHEME_EXTRACT_STRING
returns a pointer to the actual storage used by the Scheme string. If this is the case, the pointer is valid only until the next garbage collection. Note that this string may not be null-terminated; SCHEME_STRING_LENGTH
returns the number of characters in the string.
SCHEME_ENTER_STRING
converts its argument, which must be a null-terminated C string, to a Scheme string. SCHEME_ENTER_STRING
copies the characters of its arguments.
long SCHEME_EXTRACT_LONG(scheme_value)
unsigned long SCHEME_EXTRACT_UNSIGNED_LONG(scheme_value)
int SCHEME_LONG_P(scheme_value)
int SCHEME_UNSIGNED_LONG_P(scheme_value)
scheme_value SCHEME_ENTER_LONG(long)
(may GC)scheme_value SCHEME_ENTER_UNSIGNED_LONG(unsigned long)
(may GC)SCHEME_EXTRACT_LONG
extracts the numerical value of its argument, which must be an exact integer, into a C long
value. SCHEME_EXTRACT_UNSIGNED_LONG
extracts the value into an unsigned long
value.
SCHEME_LONG_P
and SCHEME_UNSIGNED_LONG_P
test whether its argument, which must be an exact integer, is a suitable argument for SCHEME_EXTRACT_LONG
or SCHEME_EXTRACT_UNSIGNED_LONG
.
Conversely, SCHEME_ENTER_LONG
and SCHEME_ENTER_UNSIGNED_LONG
convert a C number to a Scheme exact integer.The SCHEME_ENTER_LONG()
and SCHEME_ENTER_UNSIGNED_LONG()
macros may need to allocate storage when the argument is too large to fit in an immediate representation.
double SCHEME_EXTRACT_DOUBLE(scheme_value)
scheme_value SCHEME_ENTER_DOUBLE(double)
(may GC)SCHEME_EXTRACT_DOUBLE
extracts the numerical value of its argument, which must be a real, into a C double value.
Conversely, SCHEME_ENTER_DOUBLE
converts a C double into a Scheme real number.
void *SCHEME_EXTRACT_POINTER(scheme_value)
scheme_value SCHEME_ENTER_POINTER(void *)
(may GC)SCHEME_ENTER_POINTER
creates a Scheme heap object that contains a C pointer. This is useful in conjunction with SCHEME_DEFINE_EXPORTED_BINDING
for representing C functions to be called from Scheme via call-imported-c-binding
.
SCHEME_EXTRACT_POINTER
extracts the C pointer from a value created by SCHEME_ENTER_POINTER
.
The following macros and procedures are C versions of Scheme procedures. (An alphabetically sorted table follows.
int SCHEME_EQ_P(scheme_value, scheme_value)
is the C version of eq?
.
int SCHEME_EOF_OBJECT_P(scheme_value, scheme_value)
is the C version of eof-object?
.
int SCHEME_CHAR_P(scheme_value)
is the C version of char?
.
int SCHEME_INTEGER_P(scheme_value)
is the C version of integer?
.
int SCHEME_RATIONAL_P(scheme_value)
is the C version of rational?
.
scheme_value SCHEME_NUMERATOR(scheme_value)
(may GC)is the C version of numerator
.
scheme_value SCHEME_DENOMINATOR(scheme_value)
(may GC)is the C version of denominator
.
int SCHEME_REAL_P(scheme_value)
is the C version of real?
.
scheme_value SCHEME_MAKE_RECTANGULAR(scheme_value, scheme_value)
(may GC)scheme_value SCHEME_MAKE_POLAR(scheme_value, scheme_value)
(may GC)These are the C equivalents of the make-rectangular
and make-polar
Scheme procedures.
scheme_value SCHEME_MAKE_RATIONAL(scheme_value, scheme_value)
(may GC)SCHEME_MAKE_RATIONAL
creates a rational number from two exact integers. The first argument is the numerator, the second argument is the denominator.
int SCHEME_COMPLEX_P(scheme_value)
is the C version of complex?
.
scheme_value SCHEME_REAL_PART(scheme_value)
(may GC)is the C version of real-part
.
scheme_value SCHEME_IMAG_PART(scheme_value)
(may GC)is the C version of imag-part
.
scheme_value SCHEME_MAGNITUDE(scheme_value)
(may GC)is the C version of magnitude
.
scheme_value SCHEME_ANGLE(scheme_value)
(may GC)is the C version of angle
.
int SCHEME_NUMBER_P(scheme_value)
is the C version of number?
.
scheme_value SCHEME_EXACT_P(scheme_value)
is the C version of exact?
.
int SCHEME_PAIR_P(scheme_value)
is the C version of pair?
.
scheme_value SCHEME_CAR(scheme_value)
is the C version of car
.
scheme_value SCHEME_CDR(scheme_value)
is the C version of cdr
.
void SCHEME_SET_CAR(scheme_value, scheme_value)
is the C version of set-car!
.
void SCHEME_SET_CDR(scheme_value, scheme_value)
is the C version of set-cdr!
.
scheme_value SCHEME_CONS(scheme_value, scheme_value)
(may GC)is the C version of cons
.
int SCHEME_VECTOR_P(scheme_value)
is the C version of vector?
.
long SCHEME_VECTOR_LENGTH(scheme_value)
is the C version of vector-length
.
scheme_value SCHEME_VECTOR_REF(scheme_value, long)
is the C version of vector-ref
.
void SCHEME_VECTOR_SET(scheme_value, long, scheme_value)
is the C version of vector-set!
.
scheme_value SCHEME_MAKE_VECTOR(long, scheme_value)
(may GC)is the C version of make-vector
.
int SCHEME_STRING_P(scheme_value)
is the C version of string?
.
long SCHEME_STRING_LENGTH(scheme_value)
is the C version of string-length
.
char SCHEME_STRING_REF(scheme_value, long)
is the C version of string-ref
.
void SCHEME_STRING_SET(scheme_value, long, char)
is the C version of string-set!
.
scheme_value SCHEME_MAKE_STRING(long, char)
(may GC)is the C version of make-string
.
int SCHEME_SYMBOL_P(scheme_value)
is the C version of symbol?
.
scheme_value SCHEME_SYMBOL_TO_STRING(scheme_value)
(may GC)is the C version of symbol->string
.
Scheme version | C version | Can GC? |
angle | SCHEME_ANGLE | yes |
car | SCHEME_CAR | no |
cdr | SCHEME_CDR | no |
char? | SCHEME_CHAR_P | no |
complex? | SCHEME_COMPLEX_P | no |
cons | SCHEME_CONS | yes |
denominator | SCHEME_DENOMINATOR | yes |
eof-object? | SCHEME_EOF_OBJECT_P | no |
eq? | SCHEME_EQ_P | no |
exact? | SCHEME_EXACT_P | no |
imag-part | SCHEME_IMAG_PART | yes |
integer? | SCHEME_INTEGER_P | no |
make-polar | SCHEME_MAKE_POLAR | yes |
make-rational | SCHEME_MAKE_RATIONAL | yes |
make-rectangular | SCHEME_MAKE_RECTANGULAR | yes |
make-string | SCHEME_MAKE_STRING | yes |
make-vector | SCHEME_MAKE_VECTOR | yes |
number? | SCHEME_NUMBER_P | no |
numerator | SCHEME_NUMERATOR | yes |
pair? | SCHEME_PAIR_P | no |
rational? | SCHEME_RATIONAL_P | no |
real? | SCHEME_REAL_P | no |
real-part | SCHEME_REAL_PART | yes |
set-car! | SCHEME_SET_CAR | no |
set-cdr! | SCHEME_SET_CDR | no |
string? | SCHEME_STRING_P | no |
string-length | SCHEME_STRING_LENGTH | no |
string-ref | SCHEME_STRING_REF | no |
string-set! | SCHEME_STRING_SET | no |
symbol->string | SCHEME_SYMBOL_TO_STRING | yes |
vector? | SCHEME_VECTOR_P | no |
vector-ref | SCHEME_REF | no |
vector-set! | SCHEME_SET | no |
External code can call back to Scheme procedures using the following macro.
scheme_value SCHEME_CALL(scheme_value p, long nargs, ...)
(may GC)This calls the Scheme procedure p
on nargs
arguments, which are passed as additional arguments to scheme_call
. There may be at most twelve arguments. The value returned by the Scheme procedure is returned by the C procedure. Invoking any Scheme procedure may potentially cause a garbage collection.
There are some complications that occur when mixing calls from C to Scheme with continuations and threads. C only supports downward continuations (via longjmp()
). Scheme continuations that capture a portion of the C stack have to follow the same restriction. For example, suppose Scheme procedure s0
captures continuation a
and then calls C procedure c0
, which in turn calls Scheme procedure s1
. Procedure s1
can safely call the continuation a
, because that is a downward use. When a
is called Scheme will remove the portion of the C stack used by the call to c0
. On the other hand, if s1
captures a continuation, that continuation cannot be used from s0
, because by the time control returns to s0
the C stack used by c0
will no longer be valid. An attempt to invoke an upward continuation that is closed over a portion of the C stack will raise an exception.
In Scheme, if threads are implemented using continuations, the downward restriction applies to them as well. An attempt to return from Scheme to C at a time when the appropriate C frame is not on top of the C stack will cause the current thread to block until the frame is available. For example, suppose thread t0
calls a C procedure which calls back to Scheme, at which point control switches to thread t1
, which also calls C and then back to Scheme. At this point both t0
and t1
have active calls to C on the C stack, with t1
's C frame above t0
's. If thread t0
attempts to return from Scheme to C it will block, as its frame is not accessible. Once t1
has returned to C and from there to Scheme, t0
will be able to resume. The return to Scheme is required because context switches can only occur while Scheme code is running. T0
will also be able to resume if t1
uses a continuation to throw past its call to C.
Any procedure that allocates objects within the Scheme heap may trigger a garbage collection. Variables bound to values in the Scheme heap need to be registered with the garbage collector so that the value will be retained and so that the variables will be updated if the garbage collector moves the object. The garbage collector has no facility for updating pointers to the interiors of objects. Consequently, such pointers, such as the ones returned by EXTRACT_STRING
, will likely become invalid when a garbage collection occurs.
A set of macros are used to manage the registration of automatic variables and parameters with the garbage collector.
SCHEME_DECLARE_GC_PROTECT(<n>)
SCHEME_DECLARE_GC_PROTECT(<n>)
, where 1 <= <n>
< = 12, expands into a declaration which allocates storage for registering <n> variables. At most one use of SCHEME_DECLARE_GC_PROTECT
may occur in a block.
SCHEME_GC_PROTECT_<n>(<scheme_value1>, ..., <scheme_valuen>)
This expands into a statement which registers the <n> variables (lvalues) with the garbage collector. It must be within scope of a SCHEME_DECLARE_GC_PROTECT(n)
and be before any code which can cause a GC.
Note that the variables to be protected must be initialized. (With SCHEME_UNSPECIFIC
, for instance.)Otherwise, program behavior is unspecified.
SCHEME_GC_UNPROTECT()
SCHEME_GC_UNPROTECT
expands into a statement which removes the block's protected variables from the garbage collector's list. It must be called at the end of the block after any code which may cause a garbage collection. Omitting any of the three may cause serious and hard-to-debug problems. Notably, the garbage collector may relocate protected objects and invalidate scheme_value
variables which are not protected.
It is an error when a C procedure returns to Scheme, the calls to SCHEME_GC_PROTECT()
have not been matched by an equal number of calls to SCHEME_GC_UNPROTECT()
.
Global variables may also be registered with the garbage collector.
SCHEME_GC_PROTECT_GLOBAL(<value>)
SCHEME_GC_PROTECT_GLOBAL
expands into a statement which permanently registers the variable <value> (an l-value) with the garbage collector.
SCHEME_GC_UNPROTECT_GLOBAL(<value>)
SCHEME_GC_UNPROTECT_GLOBAL
expands into a statement which deregisters the variable <value> (an l-value) with the garbage collector.
The following macros can be used to create and access C objects embedded inside Scheme objects:
scheme_value SCHEME_MAKE_VALUE(type)
(may GC)type SCHEME_EXTRACT_VALUE(scheme_value, type)
type * SCHEME_EXTRACT_VALUE_POINTER(scheme_value, type)
void SCHEME_SET_VALUE(scheme_value, type, value)
scheme_value SCHEME_MAKE_AND_SET_VALUE(type, value)
(may GC)SCHEME_MAKE_VALUE
makes a Scheme object large enough to hold an object whose C type is type
. SCHEME_EXTRACT_VALUE
returns the contents of such an object cast to type
, and SCHEME_EXTRACT_VALUE_POINTER
returns a pointer to the contents of such an object. The value returned by SCHEME_EXTRACT_VALUE_POINTER
is valid only until the next garbage collection.
SCHEME_SET_VALUE
stores value
into an object created by SCHEME_MAKE_VALUE
.
SCHEME_MAKE_AND_SET_VALUE
combines SCHEME_MAKE_VALUE
and SCHEME_SET_VALUE
.
Some Scheme systems use dumped heap images to restore a previous system state. Such a scheme heap may be written into a file in a machine-independent and operating-system-independent format. The procedures described above may be used to create objects in the Scheme heap that contain information specific to the current machine, operating system, or process. A heap image containing such objects may not work correctly when resumed.
To address this problem, a record type may be given a `resumer' procedure. On startup, the resumer procedure for a type is applied to each record of that type in the image being restarted. This procedure can update the record in a manner appropriate to the machine, operating system, or process used to resume the image.
(define-record-resumer
<record-type> <procedure>)
(syntax)Define-record-resumer
defines <procedure>, which should accept one argument, to be the resumer for <record-type>. The order in which resumer procedures are called is not specified.
The <procedure> argument to define-record-resumer
may be #f
, in which case records of the given type are not written out in heap images.
When writing a heap image which would contain a reference to such a record, the Scheme implementation may refuse to write the image. If it does write the image, the effects of loading it back in are undefined.
External modules can create SRFI 9 records and access their slots positionally.
scheme_value SCHEME_MAKE_RECORD(scheme_value)
(may GC)int SCHEME_RECORD_P(scheme_value)
scheme_value SCHEME_RECORD_HAS_TYPE_P(scheme_value record, scheme_value record_type)
int SCHEME_CHECK_RECORD_TYPE(scheme_value, scheme_value int)
scheme_value SCHEME_RECORD_REF(scheme_value, long)
void SCHEME_RECORD_SET(scheme_value, long, scheme_value)
The argument to SCHEME_MAKE_RECORD
should be a shared binding whose value is a record type. In C, the fields of Scheme records are only accessible via offsets, with the first field having offset zero, the second offset one, and so forth. If the order of the fields is changed in the Scheme definition of the record type the C code must be updated as well.
Note that the variables a
and b
must be protected against the possibility of a garbage collection occuring during the call to SCHEME_MAKE_RECORD()
.
The following macros explicitly signal certain errors, and immediately return to Scheme. Signalling an error performs all necessary clean-up actions to properly return to Scheme, including adjusting the stack of protected variables. Besides that, the actual effect of signalling an error is undefined. (It is expected that a future SRFI will deal with the issue of handling error situations resulting from bugs in the program.
void SCHEME_ARITY_ERROR(int min, int max)
This signals that Scheme tried to call a C procedure with the wrong number of arguments. The min
and max
arguments denote the minimum and maximum number that the function could accept, respectively.
void SCHEME_ARGUMENT_TYPE_ERROR(int arg_pos, char *expected_explanation)
This signals that Scheme passed an argument of a wrong type to a C procedure. The arg_pos
argument specifies the position of the invalid argument (0-based). The expected_explanation
text contains a human-readable description of the type the function did actually expect.
Note to implementors: The C function is not required to provide non-local storage for the explanation. Therefore, unwinding the stack may destroy the string.
void SCHEME_OUT_OF_MEMORY_ERROR(void)
This signals that the C function ran out of memory.
void SCHEME_CHECK_BOOLEAN(scheme_value, int)
void SCHEME_CHECK_SYMBOL(scheme_value, int)
void SCHEME_CHECK_PAIR(scheme_value, int)
void SCHEME_CHECK_VECTOR(scheme_value, int)
void SCHEME_CHECK_STRING(scheme_value, int)
void SCHEME_CHECK_CHAR(scheme_value, int)
void SCHEME_CHECK_INTEGER(scheme_value, int)
void SCHEME_CHECK_RATIONAL(scheme_value, int)
void SCHEME_CHECK_REAL(scheme_value, int)
void SCHEME_CHECK_COMPLEX(scheme_value, int)
void SCHEME_CHECK_NUMBER(scheme_value, int)
void SCHEME_CHECK_RECORD(scheme_value, int)
void SCHEME_CHECK_SHARED_BINDING(scheme_value, int)
These macros raise argument type errors if their first argument does not have the required type. The second argument is the argument position passed to scheme_argument_type_error
in the case of an error.
SCHEME_CHECK_BOOLEAN
raises an error if its argument is neither #t
or #f
.
All of the C procedures and macros described above check that their arguments have the appropriate types and that indexes are in range. The following procedures and macros are identical to those described above, except that they do not perform type and range checks. They are provided for the purpose of writing more efficient code; their general use is not recommended. If a program supplies a value of the wrong type to one of these macros, program behavior is undefined.
char SCHEME_UNSAFE_EXTRACT_CHAR(scheme_value)
char * SCHEME_UNSAFE_EXTRACT_STRING(scheme_value)
long SCHEME_UNSAFE_EXTRACT_LONG(scheme_value)
unsigned long SCHEME_UNSAFE_EXTRACT_UNSIGNED_LONG(scheme_value)
double SCHEME_UNSAFE_EXTRACT_DOUBLE(scheme_value)
scheme_value SCHEME_UNSAFE_NUMERATOR(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_DENOMINATOR(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_REAL_PART(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_IMAG_PART(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_MAGNITUDE(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_ANGLE(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_CAR(scheme_value)
scheme_value SCHEME_UNSAFE_CDR(scheme_value)
void SCHEME_UNSAFE_SET_CAR(scheme_value, scheme_value)
void SCHEME_UNSAFE_SET_CDR(scheme_value, scheme_value)
long SCHEME_UNSAFE_VECTOR_LENGTH(scheme_value)
scheme_value SCHEME_UNSAFE_VECTOR_REF(scheme_value, long)
void SCHEME_UNSAFE_VECTOR_SET(scheme_value, long, scheme_value)
long SCHEME_UNSAFE_STRING_LENGTH(scheme_value)
char SCHEME_UNSAFE_STRING_REF(scheme_value, long)
void SCHEME_UNSAFE_STRING_SET(scheme_value, long, char)
scheme_value SCHEME_UNSAFE_SYMBOL_TO_STRING(scheme_value)
(may GC)scheme_value SCHEME_UNSAFE_SHARED_BINDING_REF(scheme_value s_b)
int SCHEME_UNSAFE_SHARED_BINDING_P(x)
int SCHEME_UNSAFE_SHARED_BINDING_IS_IMPORT_P(scheme_value s_b)
scheme_value SCHEME_UNSAFE_SHARED_BINDING_NAME(scheme_value s_b)
void SCHEME_UNSAFE_SHARED_BINDING_SET(scheme_value s_b, scheme_value value)
scheme_value SCHEME_UNSAFE_RECORD_TYPE(scheme_value)
scheme_value SCHEME_UNSAFE_RECORD_REF(scheme_value, long)
void SCHEME_UNSAFE_RECORD_SET(scheme_value, long, scheme_value)
type SCHEME_UNSAFE_EXTRACT_VALUE(scheme_value, type)
type * SCHEME_UNSAFE_EXTRACT_VALUE_POINTER(scheme_value, type)
void SCHEME_UNSAFE_SET_VALUE(scheme_value, type, value)
Given the following SRFI 9 record-type definition
(define-record-type :thing (make-thing a b) thing? (a thing-a) (b thing-b))
the identifier :thing
is bound to the record type and can be exported to C:
(define-exported-c-binding "thing-record-type" :thing)
Thing
records can then be made in C:
static scheme_value thing_record_type_binding = SCHEME_UNSPECIFIC; void initialize_things(void) { SCHEME_GC_PROTECT_GLOBAL(thing_record_type_binding); thing_record_type_binding = SCHEME_GET_IMPORTED_BINDING("thing-record-type"); } scheme_value make_thing(scheme_value a, scheme_value b) { scheme_value thing; SCHEME_DECLARE_GC_PROTECT(2); SCHEME_GC_PROTECT_2(a, b); thing = SCHEME_MAKE_RECORD(thing_record_type_binding); SCHEME_RECORD_SET(thing, 0, a); SCHEME_RECORD_SET(thing, 1, b); SCHEME_GC_UNPROTECT(); return thing; }
Copyright (C) Richard Kelsey and Michael Sperber (2003). All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.