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)
On Wed, Dec 17, 2008 at 2:45 PM, mosi amosat+python@gmail.com wrote:
(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?
Sounds like the string is not null terminated, so you really need to specify the length. If you want to inspect the struct type definition you can use something like this:
(slot-count (get-slot-info 'ppp 'name)) => 32
Anyway, Frode Fjeld's library "Binary-Types" might be a better solution for your problem: http://www.cliki.net/Binary-types.