[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