[gambit-list] Creating a list of C structs and returning it to Scheme

clc_xce at tutanota.com clc_xce at tutanota.com
Tue Feb 9 09:10:47 EST 2021


Hi everyone,

Long time reader, first time writer. I want to create a list of C structs and return them to Scheme with the following code:

(c-declare #<<c-list-of-structs

    typedef struct my_struct my_struct;
    struct my_struct
    {
        int* data;
    };

    ___SCMOBJ my_struct_free( void* p )
    {
        my_struct* s = (my_struct*)p;
        if( !s )
        {
            printf( "list_struct_free: %i\n", *s->data );
            free( s->data );
            return ___FIX( ___NO_ERR );
        }
        return ___FIX( ___UNKNOWN_ERR );
    }

    // create a list of n my_structs
    ___SCMOBJ create_list( int n )
    {
        ___SCMOBJ ___err = ___FIX( ___NO_ERR );
        ___SCMOBJ list = ___NUL;
        ___SCMOBJ new_list;
        my_struct* ls;

        while( n > 0 )
        {
            ls = malloc( sizeof( my_struct ) );
            ls->data = malloc( sizeof ( int ) );
            *ls->data = n;
            ___SCMOBJ element = ___NUL;
            ___err = ___STRUCT_to_SCMOBJ( ___PSTATE,
                                          ls,
                                          ___FAL,
                                          my_struct_free,
                                          &element,
                                          0 );
            new_list = ___EXT( ___make_pair ) ( ___PSTATE, element, list );
            ___EXT( ___release_scmobj ) ( list );
            ___EXT( ___release_scmobj ) ( element );
            list = new_list;
            --n;
        }
        return list;
    }

c-list-of-structs
)

;(c-define-type my-struct (struct "my_struct"))
(c-define-type my-struct (struct "my_struct" 'my-struct "my_struct_free"))
(c-define-type my-struct* (pointer my-struct))

(define create-list
  (c-lambda (int)
    scheme-object "create_list"))

(define square-my-struct!
  (c-lambda (my-struct)
    void "*___arg1.data *= *___arg1.data;"))

(define print-my-struct
  (c-lambda (my-struct) void
#<<c-print-my-struct

    printf( "my_struct: %i\n", *___arg1.data );

c-print-my-struct
))

(define test-list (create-list 10))
(map print-my-struct test-list)
(map square-my-struct! test-list)
(map print-my-struct test-list)


While this kind of works, there's two problems here: One, how do I fix the tags for my foreign objects in the list so that they're displayed as my-struct, not foreign?
Two, how do I make the GC call my release-function correctly for my_struct? 
Any help is much appreciated. Background: I have a STM32 Nucleo board, I'd like the C code on it to be able to communicate with a Scheme program on my laptop. 

Kind regards,

Georg



More information about the Gambit-list mailing list