Hi Attila,
Re: https://bugs.launchpad.net/cffi/+bug/1528719
(There is an error in the sample code, the struct is called
'struct-pair, not 'pair.)
Here is a simpler exhibition of the problem
(sumpair (convert-to-foreign '(40 . 2) '(:struct struct-pair)))
The value #.(SB-SYS:INT-SAP #X7FFFEC003560) is not of type LIST.
[Condition of type TYPE-ERROR]
So, you've said the function is call-by-value, and then you want to
pass a pointer to the structure, and it makes sense there's an error.
You have to assume a translator, because that's the only way to have a
structure by value.
I understand the desire to be able to pass a pointer instead, but my
approach would be different. I'd change the function argument
definition and extend the syntax to say that you're going to pass a
pointer, e. g.
(defcfun "sumpair" :int
(p (:struct struct-pair) :pointer))
which I would have expand to something like
(DEFUN SUMPAIR (P)
(WITH-FOREIGN-OBJECTS ((CFFI::ARGVALUES :POINTER 1) (CFFI::RESULT ':INT))
(MEM-REF
(PROGN
(LOOP :FOR CFFI::ARG :IN (LIST P)
:FOR
COUNT :FROM 0
:DO (SETF (MEM-AREF CFFI::ARGVALUES :POINTER COUNT)
CFFI::ARG))
(CFFI::CALL
(CFFI::PREPARE-FUNCTION "sumpair" ':INT '((:STRUCT STRUCT-PAIR))
':DEFAULT-ABI)
(FOREIGN-SYMBOL-POINTER "sumpair") CFFI::RESULT CFFI::ARGVALUES)
CFFI::RESULT)
:INT)))
So now you can do
(sumpair (convert-to-foreign '(40 . 2) '(:struct struct-pair)))
42
I don't like the idea of hacking up translate-into-foreign-memory
because you're doing extra work that way, and as you can see, the
expansion can be simpler than the translated case. The only
disadvantage of this approach is that you'll have to have two
different functions if you will be calling the same function with a CL
object and with a foreign pointer. I imagine that this won't happen
very often; I'm guessing this is for chaining together foreign calls
in CL, where the foreign structure never sees the light of day (=lisp
form).
(The defcfun won't expand the way I've shown yet, but the
pseudo-expansion actually can be compiled and run.)
What do you think?
Liam
i wrote up some ideas here:
https://github.com/cffi/cffi/wiki/Type-propagation-proposal
you're invited to comment/edit it.
--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“The first thing you have to do if you want to raise nice kids, is you
have to talk to them like they are people instead of talking to them
like they're property.”
— Frank Zappa (1940–1993), 'The Howard Stern Show' (1987)
dear list,
c2ffi is a tool written in C that uses the llvm/clang libs to generate
a json file from C headers. it's like gcc-xml, only much better. the
json file has explicit offsets and sizes, etc... see an example here:
https://github.com/rpav/ZMQ4L/blob/master/src/autospec/zmq.x86_64-pc-linux-…
once this json has been generated for your platform, it can be checked
into the repo and no external tool is needed afterwards.
cl-autowrap uses such json files to generate an alternative FFI API,
but i'd like to use vanilla CFFI, so i'm planning to write some code
towards this direction, but i'd like to hear some input on this before
i start working on anything...
i imagine it to be similar to how groveling works in iolib, namely:
generate the intermediate files from the json files using some ASDF
integration, and then compile the lisp files as any other lisp files.
my first question is why isn't this ASDF integration, or something
like this, ported into cffi for the gorveler? is there any other
reason besides nobody has done it yet?
https://github.com/sionescu/iolib/blob/master/src/grovel/asdf.lisp
does anyone see some showstoppers? e.g. can i lay out defcstruct
fields with explicit offsets? NOTICE-FOREIGN-STRUCT-DEFINITION
suggests so.
should this code go into a cffi-c2ffi.asd or into a standalone
project? any ideas for a name?
--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
Blaming the prince of the fools should not blind anyone to the vast
confederacy of fools that made him their prince.
Debian has relocated hdf5 includes and libraries in serial/, which
means that hdf5-cffi does not compile. See this issue:
https://github.com/HDFGroup/hdf5-cffi/issues/61. I am trying to come
up with a CFFI solution. It seems like pkg-config-cflags should do the
job for me, as pkg-config is installed and does the right thing:
pkg-config --libs hdf5
-L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5
pkg-config --cflags hdf5
-I/usr/include/hdf5/serial
However, I put a line
(pkg-config-cflags "hdf5" :optional t)
in hfd5-cffi/hdf5/grovel.lisp and got nothing useful; it is clear it
is running pkg-config but the result never makes it into the cc arg
list.
(ql:quickload :hdf5-cffi)
To load "hdf5-cffi":
Load 1 ASDF system:
hdf5-cffi
; Loading "hdf5-cffi"
[package hdf5]; pkg-config hdf5 --cflags
-I/usr/include/hdf5/serial
; cc -m64 -o /home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/grovel__grovel-tmpGHU3ALSV
-I/home/healy/languages/lisp/cffi/
/home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/grovel__grovel.c
; /home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/grovel__grovel
/home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/grovel__grovel.grovel-tmp.lisp
; cc -m64 -o /home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/h5-grovel__grovel-tmpAAURSO1
-I/home/healy/languages/lisp/cffi/
/home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/h5-grovel__grovel.c
/home/healy/.cache/common-lisp/sbcl-1.2.15-linux-x64/home/healy/languages/lisp/hdf5-cffi/hdf5/h5-grovel__grovel.c:6:18:
fatal error: hdf5.h: No such file or directory
#include <hdf5.h>
^
compilation terminated.
Is this a problem of CFFI or dies the pkg-config-cflags form need to
be somewhere else?
Liam