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,
Afficher les réponses par date
Symbols don't gc by default and they don't move, so their ___SCMOBJ representations remain constant across GC:s.
Does this solve your problem? (of course you modify get-sy to not be a function of an input argument but to perform your desired function and return the symbol return value based on the result reached.)
(c-declare "___SCMOBJ alex_symbols[123];") (define upload-sy! (c-lambda (int scheme-object) void "alex_symbols[___arg1] = ___arg2;")) (define get-sy (c-lambda (int) scheme-object "___result = alex_symbols[___arg1];"))
Mikael
2013/2/18 Alex Young alex@blackkettle.org
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 _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On 18/02/2013 17:28, Mikael wrote:
Symbols don't gc by default and they don't move, so their ___SCMOBJ representations remain constant across GC:s.
Does this solve your problem? (of course you modify get-sy to not be a function of an input argument but to perform your desired function and return the symbol return value based on the result reached.)
(c-declare "___SCMOBJ alex_symbols[123];") (define upload-sy! (c-lambda (int scheme-object) void "alex_symbols[___arg1] = ___arg2;")) (define get-sy (c-lambda (int) scheme-object "___result = alex_symbols[___arg1];"))
Ah, that's workable. I hadn't thought of that. It does seem like a duplication of effort, though - is there no way of usefully using the ___S_foo symbols from C?
On Feb 18, 2013 11:21 AM, "Alex Young" alex@blackkettle.org wrote:
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 think there are a couple of ways you can do this:
1) c-define a Scheme procedure that returns the symbols you're interested in based on some parameter. In the most general case it could be just a wrapper around string->symbol.
2) you're returning symbols so I think you want your C function to return to Scheme. Have your C function return a result code and wrap it in a Scheme procedure that maps the result code onto a symbol. You can look at Gamsock on the dumping ground for examples of how to wrap a low-level C function in a Scheme procedure that handles the Scheme objects.
On 18/02/2013 17:39, Jeff Read wrote:
On Feb 18, 2013 11:21 AM, "Alex Young" <alex@blackkettle.org mailto:alex@blackkettle.org> wrote:
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 think there are a couple of ways you can do this:
- c-define a Scheme procedure that returns the symbols you're
interested in based on some parameter. In the most general case it could be just a wrapper around string->symbol.
I had thought of that. I was rather hoping there'd be something a little cleaner though. I'll give it a try, though - it's worth benchmarking to see if it's going to cause problems.
- you're returning symbols so I think you want your C function to
return to Scheme. Have your C function return a result code and wrap it in a Scheme procedure that maps the result code onto a symbol. You can look at Gamsock on the dumping ground for examples of how to wrap a low-level C function in a Scheme procedure that handles the Scheme objects.
Yeah, I was trying to avoid having to do this. I'd be defining the return codes twice - once as ints (or whatever) and once as symbols. I guess that's all macroable away, but still... not particularly elegant.
Thanks for the suggestions :-)
Well, if you think about it, this is what Gambit does internally - in a sexp the symbol abcde is wrapped internally to (string->symbol "abcde").
In the C world, you could make a string->symbol wrapper so you'd get
___SCMOBJ alex_sy1 = string_to_symbol("alex_sy1");
etc.
With some C macro magic, perhaps that could even be written as
define_scheme_sy(alex_sy1)
or something.
(Also, have a look at string->symbol's definition, imaginably a lot of it is written in C in such a way that you could just call it directly from C, well, that might more probably not be an option too.)
2013/2/19 Alex Young alex@blackkettle.org
- you're returning symbols so I think you want your C function to
return to Scheme. Have your C function return a result code and wrap it in a Scheme procedure that maps the result code onto a symbol. You can look at Gamsock on the dumping ground for examples of how to wrap a low-level C function in a Scheme procedure that handles the Scheme
objects.
Yeah, I was trying to avoid having to do this. I'd be defining the return codes twice - once as ints (or whatever) and once as symbols. I guess that's all macroable away, but still... not particularly elegant.
Thanks for the suggestions :-)
-- Alex _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On 2013-02-18, at 10:41 AM, Alex Young alex@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