mosi | 17 Dec 15:45 2008
Picon

cffi:defcstruct, cffi:foreign-string-to-lisp question

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ó< <at> fffffŽ` <at> "
 "ABC         ÙÎ÷Só< <at> fffffŽ` <at> " 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)

_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luís Oliveira | 17 Dec 17:47 2008
Picon

Re: cffi:defcstruct, cffi:foreign-string-to-lisp question

On Wed, Dec 17, 2008 at 2:45 PM, mosi <amosat+python <at> 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>.

--

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Mirko Vukovic | 26 Dec 16:28 2008
Picon

clisp+cffi on windows+cygwin+emacsNT+slime -- the latter two prevent a library from loading

Hello,

This is a follow up on a question I posted several months ago, when I
was unable to link to the GNU Scientific Library from clisp (while
others could).

I did a bit more digging, and I narrowed down the problem, but I am
still looking for a solution.

I am running clisp built on cygwin on windows.  I mainly run clisp
through slime on top of emacs_nt (emacs built for windows).

I can link to the library, cyggsl from clisp, meaning, I start an
x-terminal, start clisp and execute:
>(cffi:load-foreign-library "/bin/cyggsl-0.dll")

But if I do that from slime, then the load fails:
Unable to load foreign library (NIL).
  FFI:OPEN-FOREIGN-LIBRARY: Cannot open library "/bin/cyggsl-0.dll":
"No such file or directory"
   [Condition of type LOAD-FOREIGN-LIBRARY-ERROR]

The problem seems to lie with slime and emacs_nt.  I had a similar
problem already, because these two would not export the DISPLAY
variable needed by some other applications.  The problem is not
universal, because I can load other libraries via slime:
cyggslcblas-0.dll for example.

I could not figure out what is it that the windows version of
emacs+slime is causing cffi not no see the library.  Anyone else has a
clue?

Thanks, (and happy holidays),

Mirko
Luis Oliveira | 27 Dec 02:51 2008
Picon

Re: clisp+cffi on windows+cygwin+emacsNT+slime -- the latter two prevent a library from loading

"Mirko Vukovic" <mirko.vukovic <at> gmail.com> writes:

> But if I do that from slime, then the load fails:
> Unable to load foreign library (NIL).
>   FFI:OPEN-FOREIGN-LIBRARY: Cannot open library "/bin/cyggsl-0.dll":
> "No such file or directory"
>    [Condition of type LOAD-FOREIGN-LIBRARY-ERROR]

Not sure how to start debugging that one. What does
(probe-file "/bin/cyggsl-0.dll") return in both situations? Or, how
about (probe-file "c:/cygwin/bin/cyggsl-0.dll") when you're running
CLISP within Emacs?

--

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/

_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Mirko Vukovic | 27 Dec 03:52 2008
Picon

Re: clisp+cffi on windows+cygwin+emacsNT+slime -- the latter two prevent a library from loading

On Fri, Dec 26, 2008 at 8:51 PM, Luis Oliveira <luismbo <at> gmail.com> wrote:
> "Mirko Vukovic" <mirko.vukovic <at> gmail.com> writes:
>
>> But if I do that from slime, then the load fails:
>> Unable to load foreign library (NIL).
>>   FFI:OPEN-FOREIGN-LIBRARY: Cannot open library "/bin/cyggsl-0.dll":
>> "No such file or directory"
>>    [Condition of type LOAD-FOREIGN-LIBRARY-ERROR]
>
> Not sure how to start debugging that one. What does
> (probe-file "/bin/cyggsl-0.dll") return in both situations? Or, how
> about (probe-file "c:/cygwin/bin/cyggsl-0.dll") when you're running
> CLISP within Emacs?
>
> --
> Luís Oliveira
> http://student.dei.uc.pt/~lmoliv/
>
>
> _______________________________________________
> cffi-devel mailing list
> cffi-devel <at> common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
>

Luis,

In my reply to Daniel I noted that I `fixed' the problem, by loading
another library before cyggsl: /lib/lapack/cygblas.dll, since cyggsl
depends on cygblas.

The curious thing is that when I do this from within clisp, I do not
need to preload the /lib/lapack/cygblas.dll.  Only when I am running
clisp from within a windows' version of emacs & slime do I need to do
that.

In the latter setup, I am accessing cygwin's clisp from the windows
side.  Usually the problem with this is that some environment variable
is not properly set (PATH, DISPLAY): Emacs inherits the windows'
environment variables, and passes them on to its sub-processes
(clisp).  I looked at PATH, and it `seems' OK.

Since I have a working solution, I am going to let it be for now.

Thanks,

Mirko
Luis Oliveira | 28 Dec 01:42 2008
Picon

New patches: 27-Dec-2008


Sat Dec 27 23:09:19 UTC 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * defcvar: don't ignore the documentation string.

  - use (setf documentation) to store the docstring.
  - add regression test.

  Bug report courtesy of James A. Crippen.

    M ./src/foreign-vars.lisp -1 +1
    M ./tests/foreign-globals.lisp -1 +4

Sat Dec 27 23:05:30 UTC 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * manual: various improvements to the DEFCFUN node

  - Add new example using an argless function.
  - Document the docstring support and exemplify it.
  - Fix some typos.

  Bug reports courtesy of James A. Crippen.

    M ./doc/cffi-manual.texinfo -4 +18

An updated tarball of CFFI's source can be downloaded here:
http://common-lisp.net/project/cffi/tarballs/cffi-081227.tar.gz

Darcsweb URL:
http://common-lisp.net/cgi-bin/darcsweb/darcsweb.cgi?r=cffi-cffi;a=summary
Stelian Ionescu | 28 Dec 22:43 2008
Picon

Re: Using preprocessor symbol as argument to :count in cstruct

On Tue, 2008-10-14 at 09:23 -0400, Hugo Duncan wrote:
> Hi,
> 
> Attatched is a simple (5-line) patch bundle that allows the use of a
> preprocessor symbol as the argument to the :count keyword in a cstruct.
> This allows grovelling of structs that contain arrays whose size is
> specified by a #defined value.  Previously, non-numeric arguments were
> ignored.
> 
> First time using darcs for anything other than retrieval, so I hope the  
> attached is in a useable form.

I've applied your patch. Sorry for the delay

--

-- 
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.

_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luis Oliveira | 29 Dec 01:42 2008
Picon

New patches: 28-Dec-2008


Sun Dec 28 21:37:58 UTC 2008  Stelian Ionescu <sionescu <at> common-lisp.net>
  * Fix %INVOKE on Clisp.

    M ./grovel/grovel.lisp -2 +5

Sun Dec 28 21:22:45 UTC 2008  Stelian Ionescu <sionescu <at> common-lisp.net>
  * Use ETYPECASE instead of COND in a few places.

    M ./grovel/grovel.lisp -21 +23

Sat Oct 11 13:00:10 UTC 2008  Hugo Duncan <hugo_duncan <at> yahoo.com>
  * Add the ability to specify a preprocessor symbol as the argument to :count in cstruct

    M ./grovel/grovel.lisp -1 +6

An updated tarball of CFFI's source can be downloaded here:
http://common-lisp.net/project/cffi/tarballs/cffi-081228.tar.gz

Darcsweb URL:
http://common-lisp.net/cgi-bin/darcsweb/darcsweb.cgi?r=cffi-cffi;a=summary
mosi | 30 Dec 14:59 2008
Picon

defcstruct and array.

Hi,
I`m experimenting with defcstruct.
I tried the following:

(defcstruct point
(nr :int)
(name :char :count 32)
(coordinates :float :count 3))

which also works like:
...
(coordinate1 :float)
(coordinate2 :float)
(coordinate3 :float)
I`m getting the values like this:
(with-foreign-object ....
(with-foreign-slots ...

nr by foreign-slot-value
name by foreign-string-to-lisp
but how do I read the array of floats with N dimensions into lisp?

Maybe I am missing something obvious here. Thanks a lot.
_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luis Oliveira | 31 Dec 01:42 2008
Picon

New patches: 30-Dec-2008


Tue Dec 30 01:45:38 UTC 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * manual: miscellaneous improvements

  - use a roman font for comments in the TeX outputs.
  - fix some typos and missing  <at> lispcmt{}s.
  - insert page breaks before each CLHS-style documentation node.
    This should make it much clearer to read and browse, at the
    expense 23 more pages in total, a ~25% increase.

    M ./doc/cffi-manual.texinfo -17 +78

An updated tarball of CFFI's source can be downloaded here:
http://common-lisp.net/project/cffi/tarballs/cffi-081230.tar.gz

Darcsweb URL:
http://common-lisp.net/cgi-bin/darcsweb/darcsweb.cgi?r=cffi-cffi;a=summary

Gmane