Nikolai Nespor nikolai.nespor@utanet.at writes:
I'm trying to develop a CFFI binding for librrd, but I'm stuck right at the begining.
The function signature I'm trying to call is
int rrd_create(int, char **);
This is probably a tricky enough case that CFFI should provide some utility functions for creating these argc/argv style string vectors.
Does something like the following work for you? It'd be nice to massage this into something worth including in src/strings.lisp...
;;; Allocate a pointer containing COUNT pointers to the strings in the ;;; Lisp SEQUENCE. (defun foreign-string-vector (sequence &optional (count (length sequence))) (let ((ptr (foreign-alloc :pointer :count count)) (i 0)) (map nil (lambda (s) (setf (mem-aref ptr :pointer i) (foreign-string-alloc s)) (incf i)) sequence) ptr))
;;; Free a string vector at PTR containing COUNT elements. (defun foreign-string-vector-free (ptr count) (loop for i below count do (foreign-string-free (mem-aref ptr :pointer i))) (foreign-free ptr))
;;; Bind ARGC and ARGV to the count and pointer of a C-style string ;;; vector, taking strings from SEQUENCE. The vector is automatically ;;; freed upon exit of BODY. (defmacro with-foreign-string-vector ((argc argv sequence) &body body) (cffi-utils:once-only (sequence) `(let* ((,argc (length ,sequence)) (,argv (foreign-string-vector ,sequence ,argc))) (unwind-protect (progn ,@body) (foreign-string-vector-free ,argv ,argc)))))
;;; Simple test of the string vector macro: (with-foreign-string-vector (argc argv '("hello" "world")) (loop for i below argc do (format t "~&;; ~D: ~A~%" i (mem-aref argv :string i))))
Thanks, James