Next: , Previous: Interacting with the Scheme heap in C, Up: C interface


7.8 Using Scheme records in C

External C code can create records and access record slots positionally using these functions & macros. Note, however, that named access to record fields is not supported, only indexed access, so C code must be synchronized carefully with the corresponding Scheme that defines record types.

— C function (may GC): s48_value s48_make_record (s48_value record-type)
— C macro: int S48_RECORD_P (s48_value object)
— C macro: s48_value S48_RECORD_TYPE (s48_value record)
— C macro: s48_value S48_RECORD_REF (s48_value record, long index)
— C macro: void S48_RECORD_SET (s48_value record, long index, s48_value value)
— C function: void s48_check_record_type (s48_value record, s48_value type-binding)

s48_make_record allocates a record on Scheme's heap with the given record type; its arguments must be a shared binding whose value is a record type descriptor (see Records). S48_RECORD_P is the type predicate for records. S48_RECORD_TYPE returns the record type descriptor of record. S48_RECORD_REF & S48_RECORD_SET operate on records similarly to how S48_VECTOR_REF & S48_VECTOR_SET work on vectors. s48_check_record_type checks whether record is a record whose type is the value of the shared binding type_binding. If this is not the case, it signals an exception. (It also signals an exception if type_binding's value is not a record.) Otherwise, it returns normally.

For example, with this record type definition:

     (define-record-type thing :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 thus:

     (define-exported-binding "thing-record-type" :thing)

and thing records can be made in C:

     static s48_value thing_record_type = S48_FALSE;
     void initialize_things(void)
     {
       S48_GC_PROTECT_GLOBAL(thing_record_type);
       thing_record_type = s48_get_imported_binding("thing-record-type");
     }
     
     s48_value make_thing(s48_value a, s48_value b)
     {
       s48_value thing;
     
       S48_DECLARE_GC_PROTECT(2);
       S48_GC_PROTECT_2(a, b);
     
       thing = s48_make_record(thing_record_type);
       S48_RECORD_SET(thing, 0, a);
       S48_RECORD_SET(thing, 1, b);
     
       S48_GC_UNPROTECT();
     
       return thing;
     }

Note that the variables a & b must be protected against the possibility of a garbage collection occurring during the call to s48_make_record.