[gambit-list] Returning a symbol to scheme from C

Marc Feeley feeley at iro.umontreal.ca
Tue Feb 19 17:17:09 EST 2013


On 2013-02-18, at 10:41 AM, Alex Young <alex at blackkettle.org> wrote:

> Hi there,
> 
> I asked this question over on StackOverflow yesterday, but it's not had 
> any joy so far.
> 
> I've got a C function behind a c-lambda which needs to do some grubbing 
> around with a select(2) call and decide on a scheme symbol to return as 
> an indication of what it did, and whether an error condition occurred. 
> Basically I want to use that symbol as a signal to drive a transition in 
> a state machine.
> 
> How one gets hold of a named symbol as a ___SCMOBJ (or anything more 
> appropriate) from C isn't explained in the docs, and the wiki seems to 
> have fallen over. It's also not immediately obvious from gambit.h 
> whether there's a macro for this purpose.
> 
> I've tried doing this:
> 
>   (define (foo) 'bar)
> 
> and taking a look at the C it generates, but it looks to me like 
> following this pattern only works if you know the offset into the symbol 
> table in advance.
> 
> Is this possible out of the box?  My workaround at the moment is to pass 
> in returnable symbols as arguments to the function, but with a larger 
> set of symbols I want to be able to return, that's going to get very 
> unwieldy very quickly.
> 
> Thanks,
> -- 
> Alex

Others on this list have proposed correct solutions to the problem of using Scheme symbol litterals in C code.  However, the solutions have a runtime cost (if string->symbol or the equivalent runtime function in C is called) or they maintain a table of symbols, which is tedious and error prone.  This is unfortunate, because the Gambit-C compiler generates for each file compiled a table of the symbols it uses.  Accessing this table from C is currently a problem because an index into the table must be used.  For example, an access to the symbol "foobar" will get translated to the macro call ___SYM(42,___S_foobar) which is usually expanded to ___sym_tbl[42].  A similar indexing approach is used for keywords, global variables and primitive functions.

In order to simplify accessing symbols, keywords, global variables and primitive functions from C, I have modified the Gambit-C back-end so that it generates macro definitions for these things.  For example, it will generate

#define ___SYM_foobar ___SYM(42,___S_foobar)

which means that C code can reference one of the Scheme source file symbols simply by prefixing the name with ___SYM_ .  Here is an example :

  (define (sign x)
    (cond ((< x 0) 'negative)
          ((> x 0) 'positive)
          (else    'zero)))

  (define sign-in-c
    (c-lambda (int)
              scheme-object
              "
                if (___arg1 < 0) ___result = ___SYM_negative;
                else if (___arg1 > 0) ___result = ___SYM_positive;
                else ___result = ___SYM_zero;
              "))

  (define (test x)
    (pp (list x (sign x) (sign-in-c x))))

  (for-each test '(-5 0 10))

  ;; output:
  ;;
  ;; (-5 negative negative)
  ;; (0 zero zero)
  ;; (10 positive positive)

This is now available on the Gambit repo.

Marc




More information about the Gambit-list mailing list