[cffi-devel] Macro-ifying a Python callback
Jeremy Smith
jeremy at decompiler.org
Wed Feb 8 18:16:15 UTC 2006
Hi,
I have a question about Lisp macros. I'm currently reading On Lisp, which is
the classic text on them, but I'm only 1/4 of the way through. I know the
CFFI developers have got the whole FFI macro thing down cold.
I have the following callback code:
(cffi:defcallback mbox-add-field :pointer ((self :pointer) (args :pointer))
(cffi:with-foreign-pointer (buf 255)
(cffi:with-foreign-pointer (val 255)
(cffi:foreign-funcall "PyArg_ParseTuple" :pointer args :string
"ss" :pointer buf :pointer val)
(mbox-add-field (cffi:foreign-string-to-lisp (cffi:mem-ref buf :string))
(cffi:foreign-string-to-lisp (cffi:mem-ref val :string)))
)
)
(py_buildvalue "s" ""))
This callback is retrieved with this code:
(cffi:get-callback ,callback)
I have 2 questions, one specific to Python.
*How do I create a callback with a gynsym'd symbol, which actually refers to
a lambda expression and not a defun'd function? The %callback thing seems
hard-wired to specifically naming it with a symbol, and creating a global
scope for it, which is okay as long as I can create non-clashing lambda's.
*The Python specific one is: Given a function which takes the following
definition:
(defpy add-field(string: key string: value)
(setf (gethash key *map*) value)
(gethash key *map*))
And would expand to this:
(cffi:defcallback add-field :pointer ((self :pointer) (args :pointer))
(cffi:with-foreign-pointer (key 255)
(cffi:with-foreign-pointer (value 255)
(cffi:foreign-funcall "PyArg_ParseTuple" :pointer args :string
"ss" :pointer key :pointer value)
(setf (gethash (cffi:foreign-string-to-lisp (cffi:mem-ref key :string))
*map* (cffi:foreign-string-to-lisp (cffi:mem-ref value :string)))
)
)
(py_buildvalue "s" ""))
That is: It calls ParseTuple to get its args, which is a multi-arg FFI
function, and are defined in a string, "s" for string, "l" for long, and so
on. Then it uses the foreign-string-to-lisp to call mem-ref to deferefence
the pointer to the string that Python returns (and Python frees it up, not
the caller).
I guess I should ask about macro stuff like this on comp.lang.lisp, but I
thought I'd try here first, as it's more specific to CFFI.
Thanks,
Jeremy.
More information about the cffi-devel
mailing list