[cffi-devel] Re: Cannot call function with char** arg
Luís Oliveira
luismbo at gmail.com
Thu Apr 20 22:08:29 UTC 2006
Nikolai Nespor <nikolai.nespor at utanet.at> writes:
> (defvar *cmd* (list "test.rrd" "--step=300" "DS:a:GAUGE:600:U:U" "DS:b:GAUGE:600:U:U" "RRA:AVERAGE:0.5:1:300"))
>
> (cffi:defcfun "rrd_create" :int (argcount :int) (args :pointer))
>
> (cffi:with-foreign-pointer (ptr (+ (reduce #'+ (map 'vector #'length
> *cmd*))(length *cmd*) 6))
> (cffi:lisp-string-to-foreign "dummy" ptr 6) ; librrd needs a dummy fst arg
> (let ((curptr (cffi:inc-pointer ptr 6)))
> (dolist (param *cmd*)
> (let ((size (1+ (length param))))
> (cffi:lisp-string-to-foreign param curptr size)
> (setf curptr (cffi:inc-pointer curptr size)))))
> (rrd-create 6 ptr))
IIUC, you're allocating a bunch of memory of stuffing the 6 strings
sequentially. This is not equivalent to what your C test code is
doing. Translated to C, the above Lisp code would look something like
this:
char *ptr = malloc(<length of *cmd* strings + 6>);
char *p = ptr;
strncpy(p, "dummy", 6);
p += 6;
for (<each string>) {
strncpy(p, <nth string>, <size of nth string>);
p += <size of nth string>;
}
rrd_create(6, ptr);
Which is not what rdd_create is expecting. Your C code should look
something like this translating to CFFI:
(with-foreign-pointer (ptr (1+ (reduce #'+ *cmd* :key #'length)))
(setf (mem-ref ptr :pointer) (foreign-string-alloc "dummy"))
(loop for i from 1 and param in *cmd* do
(setf (mem-aref ptr :pointer i) (foreign-string-alloc (nth i *cmd*))))
(rdd-create 6 ptr)
;; free the strings here
)
Hmm, we really need an array type in CFFI.
--
Luís Oliveira
luismbo (@) gmail (.) com
Equipa Portuguesa do Translation Project
http://www.iro.umontreal.ca/translation/registry.cgi?team=pt
More information about the cffi-devel
mailing list