[cffi-devel] Cannot call function with char** arg

James Bielman jamesjb at jamesjb.com
Thu Apr 20 21:30:56 UTC 2006


Nikolai Nespor <nikolai.nespor at 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 , at 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



More information about the cffi-devel mailing list