[cffi-devel] cffi:defcstruct, cffi:foreign-string-to-lisp question

mosi amosat+python at gmail.com
Wed Dec 17 14:45:12 UTC 2008


Hi,
I don`t know if this is the right group to ask, but I would appreciate some
help with the following.

The aim is to read a binary file from lisp.

The file contains a set of records, every record consists of the following
data:
(cffi:defcstruct ppp
 (nr :unsigned-int)
 (name :char :count 32)  ;; this is the problematic line 1
 (alias :char :count 12) ;; this is the problematic line 2
 (m :double)
 (t :double)
 (p :double)
 (v :double))

Now the problematic line 1 should read 32 characters from an ascii-encoded
file.
For that, I use the (defun test .....) (see below). The test converts the
cstruct with-foreign-slots through (cffi:foreign-string-to-lisp name).
The output of (test) is:
(1 "ABC                             ABC         ÙÎ÷Só<@fffffŽ`@"
 "ABC         ÙÎ÷Só<@fffffŽ`@" 28.9d0 132.4d0 3774.0d0 0.0d0)
where:
(length (second *))
>> 60
(length (third **))
>> 28
whereas I would expect the output to be:
(1 "ABC                             "
 "ABC         " 28.9d0 132.4d0 3774.0d0 0.0d0)

with length second = 32 and length third = 12.

Am I missing something?
I tried:
(cffi:foreign-string-to-lisp name 32)
(cffi:foreign-string-to-lisp name 12)

this works, the correct output is presented. But how can I get the length of
the char in the cstruct PPP?

Thank you very much,
best regards,
mosi

;;---- TEST.lisp ------
(in-package :cl-user)
(eval-when (:compile-toplevel :load-toplevel) (require :cffi))

(defpackage :test (:use :cl))

(in-package :test)

(cffi:defcfun "fopen" :pointer (path :string) (mode :string))

(cffi:defcfun "fread" :unsigned-long
 (ptr :pointer)
 (size :unsigned-long)
 (nmemb :unsigned-long)
 (stream :pointer))

(cffi:defcfun "fclose" :int (fp :pointer))

(cffi:defcstruct ppp
 (nr :unsigned-int)
 (name :char :count 32)
 (alias :char :count 12)
 (mw :double)
 (tc :double)
 (pc :double)
 (vc :double))

(defparameter *file-path* "C://the-file.bin")  ;;

(defun test ())
(let (file)
  (unwind-protect
       (progn
     (setf file (fopen *file-path* "rb"))
     (cffi:with-foreign-object (struct 'ppp)
       (fread struct (cffi:foreign-type-size 'ppp) 1 file)
       (cffi:with-foreign-slots ((nr name alias m t p v)
                     struct
                     ppp)
         (list nr
           (cffi:foreign-string-to-lisp name)
           (cffi:foreign-string-to-lisp alias)
           mw
           tc
           pc
           vc))))
    (when file (fclose file))))

;; run this by (test)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20081217/5f77c954/attachment.html>


More information about the cffi-devel mailing list