GithubHelp home page GithubHelp logo

cffi / cffi Goto Github PK

View Code? Open in Web Editor NEW
424.0 40.0 134.0 2.71 MB

The Common Foreign Function Interface

Home Page: http://common-lisp.net/project/cffi

License: MIT License

Common Lisp 94.34% Makefile 0.66% C 4.93% Batchfile 0.03% Shell 0.04%

cffi's Introduction

Build Status

What

CFFI, the Common Foreign Function Interface, purports to be a portable FFI for Common Lisp. It abstracts away the differences between the API of the native FFI's of the various Common Lisp implementations.

How

The CFFI library is composed of a Lisp-implementation-specific backend in the CFFI-SYS package, and a portable frontend in the CFFI package.

The CFFI-SYS backend package defines a low-level interface to the native FFI support in the Lisp implementation. It offers operators for allocating and dereferencing foreign memory, calling foreign functions, and loading shared libraries.

The CFFI frontend provides a more comfortable, declarative interface for defining foreign functions, structures, typedefs, enumerated types, etc. It is implemented in portable ANSI CL making use of the low-level operators exported by CFFI-SYS.

The CFFI-LIBFFI subsystem loads support for passing structs by value. It requires libffi for that.

Please consult the manual for further details, including installation instructions.

Where

Please visit Github for bug reports, feature suggestions, the latest version, and to send your contributions. CFFI also has a mailing list, and a project page at cffi.common-lisp.dev.

Notes

CFFI/C2FFI

CFFI/C2FFI is an ASDF-integrated mechanism to automatically generate a complete CFFI binding from C header files.

Its input is one .h file (with possible #includes of course), and its final output is a lisp file with the relevant CFFI binding forms.

It requires a CLI tool called c2ffi, but only for the developers of the C binding libraries, not their users. c2ffi is written in C++, and it uses Clang as a library to parse the C code, and emit the result as JSON. To skip this step, these host-specific JSON files can be checked into the repos of the binding libraries. This breaks the dependence on a working c2ffi binary and the C header files, which can be a hurdle.

These JSON files are then used to automatically generate a CL file with the corresponding CFFI forms. The generated bindings mirror the C namespace into an empty CL package as closely as possible. This means that the upper/lower case of the C names are retained. It helps with reading the original docs and with rewriting C examples into lisp. #defines are also mirrored as CL defconstants.

Binding library developers are advised to introduce another package on top of this raw layer to add more lispy constructs where appropriate (e.g. with- macros that manage resources, etc).

Until CFFI/C2FFI is properly documented, you may check out these projects as examples: hu.dwim.zlib, hu.dwim.sdl, hu.dwim.bluez, and hu.dwim.mosquitto.

Related projects

  • cl-autowrap is another project that uses c2ffi to generate CFFI bindings.

cffi's People

Contributors

3b avatar antifuchs avatar attila-lendvai avatar btomi avatar cbaggers avatar crlf0710 avatar dg1sbg avatar dkochmanski avatar dochang avatar easye avatar fare avatar ferada avatar galdor avatar gleefre avatar guicho271828 avatar jhoehle avatar jre avatar luismbo avatar markcox80 avatar paulapatience avatar ralt avatar resttime avatar s11001001 avatar sdilts avatar shinmera avatar sionescu avatar slyrus avatar soemraws avatar stassats avatar tapioco71 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cffi's Issues

Bring tests/random-tester.lisp back to life

The random tester has caught Lisp implementation bugs in the past and it would be nice to bring it back to life.

Known issues:

  1. Some type conversions are not correct. Namely, (void *) => (unsigned int). That should be uintptr_t instead.

  2. Type ranges should be generated at runtime. E.g. generating a test in a 64-bit platform should not cause said to test to overflow when running on a 32-bit platform.

Launchpad Details: #LP1039209 Luís Oliveira - 2012-08-20 20:17:00 +0000

Groveller malforms ioctl requests

On Thu, Jan 28, 2010 at 2:42 PM, Vitaly Mayatskikh wrote:

ioctl() requires request' parameter to be of type int'. CFFI
processes constants as they are of type (u)int64_t. This malforms some
requests, for example Video4Linux2 VIDIOC_* requests.

This patch adds type :int to constant groveller to solve such
problems.

--- grovel/grovel.lisp~ 2009-06-16 18:20:08.000000000 +0200
+++ grovel/grovel.lisp  2009-12-21 12:15:14.612484158 +0100
@@ -468,6 +468,8 @@ char* print_double_for_lisp(double n)
    (c-print-symbol out lisp-name t)
    (c-format out " ")
    (ecase type

  •      (:int
  •       (format out "~&  fprintf(output, "%i", (int32_t) A);" c-name))
          (integer
           (format out "
    &  if(SIGNED64P(A))%" c-name)
           (format out "    fprintf(output, "%lli", (int64_t) ~A);" c-name)

Launchpad Details: #LP622333 Luís Oliveira - 2010-08-22 16:30:00 +0000

Add with-foreign-place macro

by lichteblau: http://paste.lisp.org/display/112543

CL-USER> (defmacro with-foreign-place ((name type) &body body)
(let ((ptr (intern (format nil "&~A" (symbol-name name))
(symbol-package name))))
`(cffi:with-foreign-object (,ptr ,type)
(symbol-macrolet ((,name (cffi:mem-ref ,ptr ,type)))
,@Body))))
WITH-FOREIGN-PLACE

;; then you could write:

CL-USER> (with-foreign-place (object :pointer)
(with-foreign-place (pointer :pointer)
(setf pointer &object)
(function-that-takes-a-pointer-to-pointer &pointer)))

Launchpad Details: #LP688532 Luís Oliveira - 2010-12-10 12:29:08 +0000

cffi cannot open GNU ld scripts.

On Gentoo 64-bit, a lot of /usr/lib/lib*.so are actually GNU ld scripts, redirecting to the actual ELF libraries in /lib64.

Here is a proposed function to read them when the library cannot be opened, and redirect to the true library:

(defun load-foreign-library-if-gnu-ld-script (libname libpath error)
  (let ((newpath
         (with-open-file (stream libpath
                                 :direction :input
                                 :element-type 'character
                                 :external-format :default
                                 :if-does-not-exist nil)
           (when stream
             (let ((buffer (make-array 80
                                       :element-type 'character
                                       :fill-pointer 80)))
               (setf (fill-pointer buffer) (read-sequence buffer stream))
               (when (search "GNU ld script" buffer)
                 (file-position stream 0)
                 (loop
                   (let ((line (read-line stream nil nil)))
                     (cond
                       ((null line) (return nil))
                       ((and (< 5 (length line))
                             (string= "GROUP" (subseq line 0 5)))
                        (let* ((left  (position #\( line))
                               (ppos  (and left (position #\space line
                                                          :start (1+ left)
                                                          :test (function char/=))))
                               (right (and ppos (position #\space line :start ppos))))
                          (return 
                            (and right (subseq line ppos right))))))))))))))
    (if newpath
        (cffi::%load-foreign-library libname newpath)
        (error error))))

In load-foreign-library-path, the two calls to %load-foreigh-library could be replaced by:

  (handler-case (cffi::%load-foreign-library name path)
    (error (err)
      (LOAD-FOREIGN-LIBRARY-IF-GNU-LD-SCRIPT name path err)))

Launchpad Details: #LP941257 Pascal J. Bourguignon - 2012-02-26 05:34:53 +0000

#'asdf/run-program does not exist

Regarding this commit: 557745e

It makes a compile error and complains asdf/run-program does not exist.

; 
; caught ERROR:
;   READ error during COMPILE-FILE:
;   
;     Package ASDF/RUN-PROGRAM does not exist.
;   
;       Line: 340, Column: 62, File-Position: 12006
;

I produced this error with SBCL on Windows.
Somebody else produced this error under SBCL Debian.

I propose to use invoke or %invoke instead of asdf/run-program in the function #'pkg-flags

groveller's :define-constants doesn't work with cenum

I tried to use the cffi groveller to create a binding for <linux/videodev2.h>

The following definition:

(cenum (v4l2_buf_type :define-constants t) ((:capture "V4L2_BUF_TYPE_VIDEO_CAPTURE")))

leads to this code in the auto-generated C-file:

  /* constant section for CAPTURE */
#ifdef V4L2_BUF_TYPE_VIDEO_CAPTURE
  fputs("(cl:defconstant ", output);
  fputs("capture", output);
  fputs(" ", output);
  if(_64_BIT_VALUE_FITS_SIGNED_P(V4L2_BUF_TYPE_VIDEO_CAPTURE))
    fprintf(output, "%lli", (int64_t) V4L2_BUF_TYPE_VIDEO_CAPTURE);
  else
    fprintf(output, "%llu", (uint64_t) V4L2_BUF_TYPE_VIDEO_CAPTURE);
  fputs(")\n", output);
#else
  fputs("(cl:warn 'cffi-grovel:missing-definition :name 'CAPTURE)\n", output);
#endif

The V4L2_BUF_TYPE_VIDEO_CAPTURE is part of a C enum and no preprocessor macro.
Therefore, the #ifdef is undefined and the processed grovel file just contains the line

(cl:warn 'cffi-grovel:missing-definition :name 'CAPTURE)

instead of the expected constant definition.

I use cffi_0.11.2 and SBCL 1.1.14.30-ba008a7 on x86_64 GNU/Linux.

Launchpad Details: #LP1272009 Martin Kielhorn - 2014-01-23 17:37:11 +0000

Finish port to ABCL

A preliminary port to ABCL is already included in CFFI. It should be cleaned up and callbacks are missing.

Launchpad Details: #LP512070 Luís Oliveira - 2010-01-24 21:16:12 +0000

uffi-compat/uffi.asd interferes with UFFI

uffi.asd was added to CFFI based on the assumption that only the toplevel .asd files would be searched by default. (This was ASDF-Install's convention.) However, many systems nowadays perform a deeper search for .asd files, e.g. clbuild, and that potentially interferes with UFFI.

uffi.asd is useful because it provides a drop-in replacement for UFFI without the need to change third-party libraries.

It should be investigated whether we can leverage any ASDF features that would allow for uffi-compat/uffi.asd to bail out when UFFI is available.

Discussion: http://thread.gmane.org/gmane.lisp.cffi.devel/1720/.

Launchpad Details: #LP622241 Luís Oliveira - 2010-08-22 13:57:01 +0000

Bogus :long-long alignment in Clozure CL

On Tue, Jun 1, 2010 at 7:55 AM, Helmut Eller wrote:

I think there is a bug in CFFI with CCL's 32-bit version:

(cffi:defcunion foo-union
 (int16    :int16  )
 (uint64   :uint64 )
 )

(cffi:defcstruct bar-struct
 (tag :uint8)
 (val foo-union))

(defun foo ()
 (cffi:with-foreign-string (data "0123456789" :encoding :latin-1)
   (- (cffi:pointer-address (cffi:foreign-slot-value data 'bar-struct 'val))
      (cffi:pointer-address data))))

FOO returns 4 in SBCL and Lispworks but with CCL it's 8.

Launchpad Details: #LP622339 Luís Oliveira - 2010-08-22 16:35:27 +0000

wanted: LOAD-FOREIGN-LIBRARY report directories saught through on error.

I think it would be helpful if LOAD-FOREIGN-LIBRARY prints out the directories
that were tried to find a foreign library.

Might be difficult except for the ones listed in CFFI:FOREIGN-LIBRARY-DIRECTORIES;
in that case I'd say print out those in F-L-D and a comment "plus the OS-dependent
ones, cf. dlopen(3)" or something like that.

Launchpad Details: #LP750529 Tobias C. Rittweiler - 2011-04-04 17:37:10 +0000

`define-parse-method' section of the manual doesn't describe the macro

The manual section describing `define-parse-method' [1] doesn't seem to describe this macro.

The description of the parameters doesn't entirely match ('name' x 'type-name') and the example seems to be copied from the previous macro definition (`define-foreign-type')

[1] http://common-lisp.net/project/cffi/manual/cffi-manual.html#define_002dparse_002dmethod

Launchpad Details: #LP1042467 Diogo F. S. Ramos - 2012-08-27 22:50:04 +0000

Documentation of DEFINE-FOREIGN-TYPE & DEFINE-PARSE-METHOD

  • the example for DEFINE-FOREIGN-TYPE seems actually to be an example
    for DEFINE-PARSE-METHOD

  • the example for DEFINE-PARSE-METHOD is exactly the same, including
    the wrong operator name.

  • DEFINE-PARSE-METHOD does not come with any description.

Launchpad Details: #LP690094 Tobias C. Rittweiler - 2010-12-14 09:43:44 +0000

Bring uffi-compat up to speed with UFFI 2.0

UFFI 2.0 has new functionality, namely foreign string encodings. Attached patch by Alexandre Paes implements that functionality. Needs review and documentation.

Launchpad Details: #LP622434 Luís Oliveira - 2010-08-22 20:44:07 +0000

Groveller is too verbose

On Mon, Jun 28, 2010 at 11:49 AM, Tobias C Rittweiler wrote:

CFFI grovel outputs to DEBUG-IO (in INVOKE),
I think it should better output to ASDF::VERBOSE-OUT.

Reason is that this way, CFFI grovel will automatically
play nice with ASDF's :VERBOSE keyword parameter.

Launchpad Details: #LP622340 Luís Oliveira - 2010-08-22 16:37:10 +0000

Port darcs-new-patches.sh to git

Port darcs-new-patches.sh to git. Something like has probably already been done by Stelian Ionescu.

Launchpad Details: #LP622314 Luís Oliveira - 2010-08-22 15:58:53 +0000

need pass by reference for C API

If there is a C API defined like this:
typedef struct {} bigstruct;
typedef bigstruct* bs;
bs handle;
int create(bs* handle);
int bar(bs handle);

If I want to use that API in CFFI, then I have to do like this:
(with-foreign-object (ph :unsigned-long-long)
(let ((ret (create ph)))
(if (equal 0 ,ret)
(let ((handle (make-pointer (mem-ref ph :unsigned-long-long))))
.......

If I can do like this will much easier:

(with-foreign-object (ph :unsigned-long-long)
(let ((ret (create (pass-by-ref ph))))
(if (equal 0 ,ret)
...

-m32 or -m64 unconditionally passed to cc

cffi-grovel::cpu-word-size-flags is always set to either ("-m32") or ("-m64").

Not all compiler versions accept these flags. For instance, gcc on ARM does not accept -m32 (or -m64, for that matter).

I see that there's a "FIXME" here; unfortunately, I don't have any really great suggestions on how to detect what flags are appropriate.

Launchpad Details: #LP767879 R. Matthew Emerson - 2011-04-20 23:41:11 +0000

Link with -lpthread on OpenBSD

Installation of GSLL on OpenBSD5.3 fails with the error:

  • (ql:quickload "gsll")
    sbcl:/usr/local/lib/libffi.so.6.1: undefined symbol 'pthread_mutex_unlock'
    sbcl:/usr/local/lib/libffi.so.6.1: undefined symbol 'pthread_mutex_lock'
    sbcl:/usr/local/lib/libffi.so.6.1: undefined symbol 'pthread_mutex_init'

I suspect this might be because libffi needs to be linked with -lpthread on OpenBSD.

A seperate issue - OpenBSD names libffi:

/usr/local/lib/libffi.so.0.0

Launchpad Details: #LP1232196 Adam Jensen - 2013-09-27 18:54:51 +0000

FreeBSD 64bit arch detection

OS: FreeBSD 8.1 64bit

SBCL version 1.0.34
CFFI version 0.10.6

Installing CFFI using asdf-install I get the following error

/usr/bin/ld: /var/tmp//ccoWlJBC.o: relocation R_X86_64_32 can not be used when making a shared object; recomp le with -fPIC

In tests/GNUmakefile:
ARCH = $(shell uname -m)

The arch type returned from uname -m is amd64 where x86_64 is expected.

Launchpad Details: #LP675844 Mathew Prokos - 2010-11-16 03:46:38 +0000

Document handling of callbacks from foreign threads

Calls to functions defined via cffi:defcallback coming from foreign threads (i.e., threads not created by the Lisp implementation) is not supported in all Lisps.

Clozure CL, for example, seems to this automagically. Gary Byers described the issue
in detail in this message
http://www.clozure.com/pipermail/openmcl-devel/2003-May/004781.html.
Although he says "that code isn't written yet", apparently it has been
written since then.

Here's a quick test to check whether your Lisp supports callbacks from
random threads.

(in-package :cffi)

(load-foreign-library "libpthread.so.0")

(defcallback foo :pointer ((arg :pointer))
(declare (ignore arg))
(print 'called-into-lisp-from-foreign-thread)
(null-pointer))

(defctype pthread-t :unsigned-long)

(with-foreign-object (th 'pthread-t)
(foreign-funcall "pthread_create" :pointer th :pointer (null-pointer)
:pointer (callback foo) :pointer (null-pointer))
(foreign-funcall "pthread_join" pthread-t (mem-ref th 'pthread-t)
:pointer (null-pointer)))

We should at some point run it on the supported Lisps and note down
which ones support this. Then add that information to the manual and
possibly push something informative to FEATURES on Lisps that don't
support this.

Launchpad Details: #LP622256 Luís Oliveira - 2010-08-22 14:33:02 +0000

defctype and inner structs do not seem to play nicely

With the attached code, the following transcript shows the difference:

CL-USER> (ql:quickload "CFFI")
To load "cffi":
Load 1 ASDF system:
cffi
; Loading "cffi"
..
("CFFI")
CL-USER> (use-package "CFFI")
T
CL-USER> (load "/Users/woudshoo/Development/Source/Lisp-Outside-ASDF/cffi-bugs/struct-bug")
STYLE-WARNING: Undefined alien: "get_outer"
T
CL-USER> (setup)
#<FOREIGN-LIBRARY CFFI.O-943 "cffi.o">
CL-USER> (get-outer-works)
"Outer Translated, a = 1, b= <Inner Translated, a = 2, b= 3>"
CL-USER> (get-outer-bug)
"Outer Translated, a = 1, b= <#.(SB-SYS:INT-SAP #X0018E004)>"

The difference in the result is that in '(get-outer-works)' the inner struct is translated and
in the bug version it is not.

As far as I can tell the only relevant difference is in the declaration of the outer structs:

(defcstruct (outer-struct :class outer-struct-type)
(a :int)
(b (:struct inner-struct)))

vs

(defctype %bug-struct (:struct inner-struct))

(defcstruct (outer-struct-bug :class outer-struct-type-bug)
(a :int)
(b %bug-struct))

Launchpad Details: #LP1172592 Willem Rein Oudshoorn - 2013-04-25 06:48:09 +0000

Support for cleanup actions on arguments performed when callback returns

To be reviewed and documented.
On Sun, Jul 26, 2009 at 10:06 PM, Kalyanov Dmitry wrote:

I am trying to create a binding for gobject library with CFFI.

CFFI works extremely well, however I have a use case that is not covered by
CFFI.

Basically, I want to define foreign types that should "clean up" after
themselves when they are used as types for callback arguments.

I have following use cases for this:

  1. I want to have a structure created when callback is entered and have its
    contents copied to foreign structure when callback returns.

  2. I want to have wrappers that contain a pointer to foreign structure.
    However, I want to ensure that operations on wrapper signal errors when
    callback returns (because pointer points to a stack-allocated structure). This
    is needed to ensure that no operations are done on invalid pointer.

The attached patch provides suggested change: foreign types may specify that
additional actions should be performed when the callback returns. This is
achieved by adding new generic function CLEANUP-TRANSLATED-OBJECT-FOR-
CALLBACK. Additional generic function HAS-CALLBACK-CLEANUP is called at
macroexpansion time as an optimization to remove unnecessary calls to CLEANUP-
TRANSLATED-OBJECT-FOR-CALLBACK.

Attached is a test case that demonstrates the usage and checks for correctness
of behavior.

If there are obstacles for adding this patch, I would be happy to work on
them.

Launchpad Details: #LP622274 Luís Oliveira - 2010-08-22 15:19:17 +0000

GC should be allowed to run during a foreign function call

It has been observed that in Allegro CL, when making a foreign function call, GC may be prevented from running. Preventing GC from running can deadlock the entire instance.

There should be a test that tests whether or not GC is able to run during a foreign function call.

Refer to the following discussion (http:///msg02378.html) for additional information.

Launchpad Details: #LP1211664 Felix Filozov - 2013-08-13 07:54:36 +0000

Missing device specifier in the groveler on windows

The groveler fails to start the c-compiler with the right include pathes on windows. This is due too the usage of (directory-namestring) to get the directory component of the path. This does not include the device on windows.

The fix uses the function namestring-prefix in the attached lib to extract the directory together with the device specifier. This fixes the problem, at least with ccl-1.8 on windows 7-64-bit.

Launchpad Details: #LP985103 Karl Heinrichmeyer - 2012-04-18 17:47:02 +0000

Handling narrow return types on x86

On Thu, Mar 26, 2009 at 9:03 PM, Jean-Claude Beaudoin
wrote:

Recent versions of GCC appear to be leaving spurious bits in the %eax
register used to return the value of a C function on x86 based platforms
when the return type is narrower than 32 bits (ie: short or char). SBCL
does not defend itself against such register pollution and will return an
incorrect value made up of those spurious bits in addition to the intended
value. A partial fix for "signed" short and char has appeared in SBCL
1.0.25 but the "unsigned" cases are still vulnerable. I suggest that CFFI
should defend itself against that dangerously permissive handling of narrow
return types in SBCL through the use of a few filtering functions to be
applied in those relevant cases, at least until SBCL fixes the issue for
good.

Before any fix is commited, this bug should be reproduced/investigated
(it deserves to be well explained somewhere in the source code) and a
test case written.

Further discussion: http://thread.gmane.org/gmane.lisp.cffi.devel/1569

Launchpad Details: #LP622251 Luís Oliveira - 2010-08-22 14:24:25 +0000

Implement the C99 complex type

Suggested by Tamas K. Papp.

Prototype code:

(defmethod translate-from-foreign (ptr (type complex-float-type))
(complex (mem-aref ptr :float 0) (mem-aref ptr :float 1)))

(defun complex-float-aref (ptr index c)
(let ((p (* (foreign-type-size :complex-float) index)))
(setf (mem-aref p :float 0) (realpart c)
(mem-aref p :float 1) (imagpart c))))

Launchpad Details: #LP622260 Luís Oliveira - 2010-08-22 14:44:10 +0000

foreign-string-alloc and :string should be able to ignore errors

Currently, the following is possible:
(let ((babel-encodings:suppress-character-coding-errors t))
(foreign-string-alloc "pão" :encoding :ascii))

However, it's not very convenient, particularly when using :string types. Even more so, if the :string type is used in a callback function.

Feature requested by Michael Raskin: http://thread.gmane.org/gmane.lisp.cffi.devel/1852

Launchpad Details: #LP622421 Luís Oliveira - 2010-08-22 20:16:16 +0000

defbitfield syntax

On Fri, Oct 2, 2009 at 2:22 PM, Bart Botta wrote:

A few weeks ago on #lisp I suggested extending the defbitfield syntax
to allow defining elements in terms of preceding elements in the
bitfield (see http://paste.lisp.org/display/87065 for a sample usage
and implementation).

Needs: review, documentation, tests.

Launchpad Details: #LP622270 Luís Oliveira - 2010-08-22 15:09:39 +0000

Not enough type checking on API boundaries

James Anderson pointed to some examples of how the CFFI API doesn't perform adequate type checking resulting in cryptic errors coming from CFFI internals: http://article.gmane.org/gmane.lisp.cffi.devel/2425

E.g., (foreign-slot-value s 'something-thats-not-a-struct-type 'field) will yield things like:

; caught WARNING:
;   Error during compiler-macroexpansion of
;   (CFFI::FOREIGN-SLOT-SET #:STORE4 S ...). Use *BREAK-ON-SIGNALS* to
;   intercept.
;   
;    There is no applicable method for the generic function
;      #<STANDARD-GENERIC-FUNCTION CFFI::SLOTS (1)>
;    when called with arguments
;      (#<CFFI::FOREIGN-TYPE SOMETHING-THATS-NOT-A-STRUCT-TYPE>).

We have all the information to properly point out that a struct type was expected but we got something else. We can do it at compile time even.

Launchpad Details: #LP1190418 Luís Oliveira - 2013-06-13 00:11:33 +0000

Regression for Allegro 8.1 causing Segmentation Fault (11).

Hi there,

The following patch causes Allegro 8.1 to segfault when calling a function with strings (or more specifically, varargs).

53af387

(cffi:defcfun ("zsocket_connect" zsocket_connect) :int
  (socket :pointer)
  (format :string)
  &rest)

After the patch, calling zsocket_connect causes the segfault every time.

If I either revert the commit, or bump up the versions to 8.2 instead of 8.1, the problem goes away. Will you accept a pull request to bump the version up to 8.2? It seems safe enough to do so.

DEFCFUN and unsigned-long-long behaving badly on 64-bit Allegro CL

Bug report sent to Franz.

(in-package :cl-user)

#||

#include <limits.h>

unsigned long long ullong(unsigned long long n)
{
printf("ullong(%llu)\n", n);
    return n == ULLONG_MAX ? n : 42;
}

||#

(ff:def-foreign-call (ullong "ullong")
    ((n :unsigned-nat (unsigned-byte 64)))
  :returning (:unsigned-nat (unsigned-byte 64))
  :call-direct t ; setting this to nil fixes the symptoms.
  :arg-checking nil
  :strings-convert nil)

(defun test-ullong ()
  (ullong (1- (expt 2 64))))

;; CL-USER> (ullong (1- (expt 2 64)))
;; ullong(18446744073709551615)
;; 18446744073709551615 ; OK
;;
;; But when :call-direct kicks in:
;; CL-USER> (test-ullong)
;; ullong(18446744073709551615) ; argument was fine
;; -1 ; but return value is wrong

Launchpad Details: #LP914500 Luís Oliveira - 2012-01-10 22:06:22 +0000

Strings cannot be passed together with structs by value

(defcstruct struct)

(defcfun fun :void
  (struct (:struct struct))
  (string :string))

(fun () "string")

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION TRANSLATE-INTO-FOREIGN-MEMORY (5)>
when called with arguments
  ("string" #<FOREIGN-STRING-TYPE :UTF-8>
   #.(SB-SYS:INT-SAP #X7FFFF49CFFF0)).

Launchpad Details: #LP1233238 Stas Boukarev - 2013-09-30 15:38:06 +0000

Better support for application delivery

The interaction between CFFI and the application delivery support provided by the various Lisps we support is not well tested nor documented in the manual.

Some discussion and patches (to be reviewed) regarding one such example, cffi-grovel wrapper libraries: http://thread.gmane.org/gmane.lisp.cffi.devel/1504/focus=1552

SBCL-specific discussion: http://thread.gmane.org/gmane.lisp.cffi.devel/1655/focus=1811

Launchpad Details: #LP622264 Luís Oliveira - 2010-08-22 14:55:37 +0000

#'pkg-flags returning blank string

Opening this issue since somebody reported a problem.

(pkg-flags "libffi") 

The evaluation above does not appear to be able to grab the correct package flags on a Linux system and thus gcc crashes.
It seems as if pkg-config is unreliable?

Some Talk in the commit:
4d5479d

Port to 64-bit Windows Clozure CL

64-bit windows Clozure CL fails a lot of tests. The following patch fixes some of them.

cffi/src/cffi-openmcl.lisp
184,187c184,189
< #+32-bit-target (:long %get-signed-long)
< #+64-bit-target (:long ccl::%%get-signed-longlong)
< #+32-bit-target (:unsigned-long %get-unsigned-long)
< #+64-bit-target (:unsigned-long ccl::%%get-unsigned-longlong)

#+(or 32-bit-target windows) (:long %get-signed-long)
#+(and 64-bit-target
(not windows)) (:long ccl::%%get-signed-longlong)
#+(or 32-bit-target windows) (:unsigned-long %get-unsigned-long)
#+(and 64-bit-target
(not windows)) (:unsigned-long ccl::%%get-unsigned-longlong)

Reported by Louis Höfler.

Launchpad Details: #LP622423 Luís Oliveira - 2010-08-22 20:20:13 +0000

LOAD-FOREIGN-LIBRARY on defined libraries obfuscates errors

Lispbuilder-sdl includes a "cocoahelper" library:

(define-foreign-library cocoahelper
(:darwin (:or (:framework "cocoahelper")
(:default "cocoahelper"))))

Trying to (load-foreign-library 'cocoahelper) causes the error:

Unable to load any of the alternatives:
((:FRAMEWORK "cocoahelper") (:DEFAULT "cocoahelper"))
[Condition of type CFFI:LOAD-FOREIGN-LIBRARY-ERROR]

which doesn't exactly help in trying to figure out what is going from. The underlying implementation in this case reported the overly verbose -- but more useful -- error:

Error opening shared object "/Users/nikodemus/quicklisp/dists/quicklisp/softwar...":
dlopen(/Users/nikodemus/quicklisp/dists/quicklisp/software/lispbuilder-20101006-svn/lispbuilder-sdl/cocoahelper/cocoahelper.dylib, 10): no suitable image found. Did find:
/Users/nikodemus/quicklisp/dists/quicklisp/software/lispbuilder-20101006-svn/lispbuilder-sdl/cocoahelper/cocoahelper.dylib: mach-o, but wrong architecture.

Launchpad Details: #LP661117 Nikodemus Siivola - 2010-10-15 10:43:35 +0000

FOREIGN-SLOT-SET compiler macro generates invalid code

On Wed, Aug 5, 2009 at 5:07 PM, Nikodemus Siivola wrote:

2009/8/5 Vitaly Mayatskikh :

Gives me:
; in: LAMBDA NIL
;     (CFFI::FOREIGN-SLOT-SET #:STORE651
;                             (SB-PCL::ACCESSOR-SLOT-VALUE #:TMP650 'RAW)
;                             'MY-STRUCT 'FOO)
; --> SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::MEM-SET CFFI-SYS:%MEM-SET
; --> LET SETF SB-KERNEL:%SET-SAP-REF-8
; ==>
;   (LET #:TMP11
;     #:TMP10
;     #:TMP9)
;
; caught ERROR:
;   Malformed LET bindings: #:TMP11.

and several others errors

Clisp loads the same code ok. Is it a bug?

Yes, it's a but -- but I believe a bug in CFFI. Explanation follows.
(Example demonstrating an alternative way to trigger comes right at
the end.)

In the expansion, this is the problematic form:

(DEFMETHOD (SETF MY-STRUCT-FOO) ((INST MY-STRUCT) NEW)
 (SETF (CFFI:FOREIGN-SLOT-VALUE (SLOT-VALUE INST 'RAW) 'MY-STRUCT
                                'FOO)
       NEW))

first off, this probably does not do what you think it does: the new value is
the first argument, not the last. Anyways, digging deeper, the trouble
arises with
the result of the SETF expansion here:

(CFFI::FOREIGN-SLOT-SET #:STORE968 (SB-PCL::ACCESSOR-SLOT-VALUE #:TMP967 'RAW)
                       'MY-STRUCT 'FOO)

Note that PCL has replaced the SLOT-VALUE with ACCESSOR-SLOT-VALUE. Had it
been a (SETF SLOT-VALUE) it would now be ACCESSOR-SET-SLOT-VALUE.

CFFI has a compiler macro for FOREIGN-SET-SLOT,

(SETF (CFFI:MEM-REF (SB-PCL::ACCESSOR-SLOT-VALUE #:TMP10 'RAW) ':UCHAR 0)
       #:STORE11)

which in turn has a SETF-expander, producing

(LET* ((#:TMP972
       ((SB-PCL::.IGNORE.
         (LOAD-TIME-VALUE
          (SB-PCL::ENSURE-ACCESSOR 'SB-PCL::READER
                                   '(SB-PCL::SLOT-ACCESSOR :GLOBAL RAW
                                     SB-PCL::READER)
                                   'RAW)))))
      (#:TMP971 (DECLARE (IGNORE SB-PCL::.IGNORE.)))
      (#:TMP970
       (SB-EXT:TRULY-THE (VALUES T &OPTIONAL)
                         (FUNCALL
                          (LOCALLY
                              (DECLARE (SB-EXT:MUFFLE-CONDITIONS
STYLE-WARNING))
                            #'(SB-PCL::SLOT-ACCESSOR :GLOBAL RAW
                                                     SB-PCL::READER))
                          #:TMP10))))
 (MULTIPLE-VALUE-BIND
       (#:STORE973)
     #:STORE11
   (PROGN
     (CFFI::MEM-SET #:STORE973
                    (LET #:TMP972
                      #:TMP971
                      #:TMP970)
                    ':UCHAR 0)
     #:STORE973)))

where the malformed LET appears. This is because ACCESSOR-SLOT-VALUE is not a
settable place, but rather a macro that expands into a LET form.

I'm inclined to blame the compiler-macro for FOREIGN-SLOT-SET, which puts the
original SLOT-VALE form in a context where it becomes a (SETF SLOT-VALUE.)
While arguably the code walker should take expansion of compiler-macros into
account, compiler macros are not allowed the change the semantics of their
arguments -- which this one does.

Notice how the same error can be provoked without the PCL code walker:

(defun my-bad (x z)
 (setf (cffi:foreign-slot-value (let ((y (x-y x)))
                                  (y-foreign y))
                                'my-struct
                                'foo)
       z))

Unless the contract of (SETF FOREIGN-SLOT-VALUE) is that the first
(second) argument
must be a settable place itself, the compiler-macro is broken.

Cheers,

 -- Nikodemus

Launchpad Details: #LP622273 Luís Oliveira - 2010-08-22 15:16:42 +0000

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.