"Luís Oliveira" luismbo@gmail.com writes:
On Mon, Jan 19, 2009 at 5:50 AM, John Fremlin jf@msi.co.jp wrote:
The advantage of the change is that ptr-var is now actually a foreign pointer as it is in all other cffi-ports.
You might not want to pass the ptr-var directly to a function, but actually use it as a foreign pointer.
For a concrete example, using the recvmsg(2) system call, you pass a structure containing an iovec, which is itself a structure containing the base address and length of the buffer into which the message body should be written.
That definitely looks like a legitimate use-case. Let us know when you figure out what the first argument to FF:FSLOT-ADDRESS-TYPED should be.
Here is the new magic based on fresh clues from Duane . . . This one seems to work. A thorough test suite would be great though!
(defun make-shareable-byte-vector (size) "Create a Lisp vector of SIZE bytes which can be passed to ;WITH-POINTER-TO-VECTOR-DATA." (make-array size :element-type '(unsigned-byte 8) :allocation :static-reclaimable))
(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body) "Bind PTR-VAR to a foreign pointer to the data in VECTOR. Not safe except with vectors allocated by MAKE-SHAREABLE-BYTE-VECTOR and possibly arrays of type simple-array (unsigned-byte 8) (*)." ;;; An array allocated in static-reclamable is a non-simple array in ;;; the normal Lisp allocation area, pointing to a simple array in the ;;; static-reclaimable allocation area. Therefore we have to get out ;;; the simple-array to find the pointer to the actual contents. (with-unique-names (simple-vec) `(excl:with-underlying-simple-vector (,vector ,simple-vec) (let ((,ptr-var (ff:fslot-address-typed :unsigned-char :lisp ,simple-vec))) ,@body))))