Hello,
I'm working on a CFFI interface to the Perl API (I thought it would be fun - ha!) and I need to be able to do C-style pointer arithmetic. That is, I have a foreign pointer declared with DEFCVAR and I need to alter the address stored there. I couldn't see a way to do this with CFFI, so I created a new foreign type called :ADDRESS that would treat the foreign pointer as an integer value that I could modify.
Here's my code:
(defvar *pointer-size* (foreign-type-size :pointer) "The size of a pointer on the current platform, in bytes.")
(ecase *pointer-size* (1 (defctype :address :uint8)) ; unlikely (2 (defctype :address :uint16)) ; possible (4 (defctype :address :uint32)) ; most common (8 (defctype :address :uint64))) ; possible
(defmacro address-incf (address &optional (n 1)) "Increment ADDRESS by N pointers, like ++i on a C pointer." `(incf ,address (* ,n *pointer-size*)))
(defmacro address-decf (address &optional (n 1)) "Decrement ADDRESS by N pointers, like --i on a C pointer." `(decf ,address (* ,n *pointer-size*)))
(defmacro address-ref (address type) "Dereference ADDRESS to get the TYPE it points to, like MEM-REF." `(mem-ref (make-pointer ,address) ,type))
This does work for my purposes, but is there a better way using CFFI internals?
Thanks, -Stuart