Sounds interesting. I like the idea of putting everything into one declaration instead of having two as before. I think "to-c" and "from-c" are fine names. A cuter name would just make it easier to get the two directions mixed up, IMHO.
I've got one question and one suggestion. Excuse me if they're dumb, because I'm not too up-to-date on the workings of C-FFI.
1) How does the translator interface express more complex C values? Say, I want the "to-c" clause to send a struct to the C code? Can I just return an object allocated by foreign-object-alloc?
2) Is there any way to make translations optional, and only invoke them on particular arguments in a given function declaration?
I'm also thinking about one other thing. Say I'm wrapping this function:
void cairo_line_to(cairo_t* cr, double x, double y);
I'd like the Lisp declaration to be as if the function was:
(defun cairo-line-to (cr pt) ...) where 't' is a 'point' structure or maybe just a (x . y) cons cell. Would it be reasonable to include that kind of translation in the FFI, or would it be more prudent to put that in a higher layer?
Sincerely, Rayiner Hashem
On 8/3/05, Luis Oliveira luismbo@gmail.com wrote:
Hello,
I'm reworking the type translator interface. The idea is to simplify and allow for more flexibility. I'll start with some examples:
This is how the boolean type would be defined with the current interface:
(defctype boolean :int)
(define-type-translator boolean :in (arg result-var) "Type translator to convert t/nil to a C boolean." (values `(if ,arg 1 0) nil))
(define-type-translator boolean :result (arg result-var) "Type translator to convert C booleans to t/nil." (values `(if (zerop ,arg) nil t)))
First thing I'm changing is :in/:return, the names don't make sense when we think about callbacks, the :return translation is applied for the arguments and :in for the callback's return value. So I picked :to-c and :from-c. Can someone suggest better names?
And this is how my interface would look like:
(define-type-translation (boolean :int) "Converting between C ints and Lisp booleans." :to-c (if &value 1 0) :from-c (if (zerop &value) nil t))
It takes care of the defctype unless the first arg isn't a list. If it were just 'boolean' defctype woudn't be used (eg. when defining a type-translating for a struct type). Hmm, is this extra syntax re defctype overkill?
Also it sets up &value with symbol-macrolet.
Another example, the string type. Before:
(defctype string :pointer)
(define-type-translator string :to-c (arg result-var) "Type translator for converting Lisp strings to C string." (values `(foreign-string-alloc ,arg) `((foreign-string-free ,result-var))))
(define-type-translator string :from-c (arg result-var) "Type translator for C string values." `(foreign-string-to-lisp ,arg))
After:
(define-type-translation (string :pointer) "Converting between C and Lisp strings." :in (let ((&var (foreign-string-alloc &value))) (unwind-protect (&body) (foreign-string-free &var))) :to-c (foreign-string-alloc &value) :from-c (foreign-string-to-lisp &value))
Here we have an extra translation :in, used when we are actually passing something to a foreign function (the :to-c translation is used, in case :in is undefined). Here we have to explicitly write the unwind-protect, I think the translation becomes more readable this way. :in also sets up a few more (symbol-)macros, &var and &body whose meaning should be obvious.
Getting to decide where &body goes (ie. not having to be restricted to a unwind-protect form as before) gives us the ability to do this:
(define-type-translation (string :pointer) "Converting between C and Lisp strings." :in (with-foreign-string (&var &value) (&body)) :to-c (foreign-string-alloc &value) :from-c (foreign-string-to-lisp &value))
This way the string is stack allocated (if the lisp supports this).
In this last example, I indented the code in a different way, I'm not yet happy with the syntax, any comments or suggestions regarding syntax, naming, etc.. will be most appreciated.
Also, the :to-c/:from-c translations, unlike :in, don't have access to &body as I couldn't think of a situation where this would be necessary. Am I missing something?
-- Luís Oliveira http://student.dei.uc.pt/~lmoliv/ Equipa Portuguesa do Translation Project http://www2.iro.umontreal.ca/~pinard/po/registry.cgi?team=pt _______________________________________________ cffi-devel mailing list cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel