Victor | 14 Jul 16:37 2015

Using CFFI: dealing with a writeback buffer

Hi all,

I don't know if it is the best place to ask this question, but I'll try it. I am trying to wrap around a following function:

OGRErr OSRExportToProj4(OGRSpatialReferenceH r, char **buff);

This function allocates the string and assigns it to the (char*) pointer passed as buff and then its
contents should be copied into a C string and the obtained pointer released via CPLFree();

So, basically, in C a typical usage would be:

  char *proj = NULL:
  OSRExportToProj4(handle, &proj);
  printf("%s\n", proj);
  CPLFree(proj);

And the question is: how is this function should be wrapped with CFFI?

Thanks,
Victor

-- реклама -----------------------------------------------------------
FREEhost.UA - быстрый и удобный хостинг доступный каждому.
http://freehost.com.ua/unix/

Liam Healy | 11 Jul 22:45 2015
Picon

Path discovery and simplification of libffi-unix.lisp

I'm trying to catch up on recent changes made to CFFI with regard to
path discovery with the idea of simplifying code, both in CFFI itself,
and in GSLL (which uses CFFI). The grovel option pkg-config-cflags
seems to permit the elimination of some other code in e.g.
libffi-unix.lisp. With the presence of (pkg-config-cflags "libffi"
:optional t), it seems like these could be eliminated:

#+darwin
(cc-flags "-I/opt/local/include/")

#+openbsd
(cc-flags "-I/usr/local/include")

and these

#+darwin
(include "ffi/ffi.h")
#-darwin
(include "ffi.h")

could be replaced with
(include "ffi.h")

Is that correct? Not a darwin or openbsd user so can't test myself.

Thanks,
Liam

Luís Oliveira | 29 May 01:14 2015
Picon

CFFI 0.15.0 released

Hello,

I've just released CFFI 0.15.0.
https://github.com/cffi/cffi/wiki/NEWS#version-0150

Cheers,

--

-- 
Luís Oliveira
http://kerno.org/~luis/

markus | 27 May 23:04 2015
Picon

markus.ingvarsson <at> gmail.com has indicated you're a friend. Accept?

I would like to add you as a friend

Accept
Decline
Mirko Vukovic | 23 May 16:21 2015
Picon

How to customize cffi-grovel:*cc*, *cc-flags*?

Hello,

in order to get GSLL to run on Windows7+CCL+MSYS2+GSL, I needed to customize *cc* and *cc-flags*.  Right now, I do this by modifying the code in grovel.lisp, as for *cc-flags*:

   #+(and windows msys2)
   (list "-I" "E:/msys64/mingw64/lib/libffi-3.2.1/include/"
         "-I" "c:/Users/977315/quicklisp/dists/quicklisp/software/cffi_0.14.0/")


(I prefer not to modify system-wide environment variables on my PC)

I see alternate ways of achieving the same effect:
  1. Write own gsll loader that customizes *cc* and *cc-flags*
  2. Write own cffi-libffi loader that customizes the variables
  3. (somehow) advise gsll or cffi-libffi loaders in my lisp-init files to customize the variables
  4. Modify environment variables for my process.
What is the advised way to do this?  I would prefer 3: in my lisp startup file, I (somehow) write some advice code to asdf that customize *cc* and *cc-flags*.  But I don't know how to do that.

Thank you,

Mirko

Marshall Mason | 1 May 01:28 2015
Picon

Error when passing struct by value

Hello,
I'm using SBCL version 1.2.4, CFFI version 0.14.0, and libffi version 3.1. I've been trying to pass a struct by value using CFFI and libffi. I'm a newbie to both CFFI and Lisp so I had to piece this together from the manual as well as some of the unit tests that come with CFFI. I'm getting an error that I just can't get past:

The value READ-FUNC is not of type SB-SYS:SYSTEM-AREA-POINTER

The library I'm trying to wrap is libvorbisfile, which decodes Ogg Vorbis files. It has an init function called ov_open_callbacks:

int ov_open_callbacks(void *datasource, OggVorbis_File *vf, const char *initial, long ibytes, ov_callbacks callbacks);

The part it's choking on is the last argument, a struct, passed by value, of callback functions:

typedef struct {
    size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);
    int    (*seek_func)  (void *datasource, ogg_int64_t offset, int whence);
    int    (*close_func) (void *datasource);
    long   (*tell_func)  (void *datasource);
} ov_callbacks;

The library is designed to use one of a few static structs defined in a header file. Since it's defined in the header file and not in libvorbisfile.so, I must create CFFI translation code. There were a lot of other structs I had to wrap with CFFI as well. Here is my code:

http://pastie.org/10122885

Does anyone have any clues about what I'm doing wrong here?

(Regarding my previous email about getting CFFI working on Debian jessie, it turns out the Debian version of cl-alexandria is missing a file and cl-cffi is buggy, so I just added the missing file and installed the CFFI source by hand. Thanks for the response, Fau.)

Marshall
Marshall Mason | 29 Apr 22:51 2015
Picon

Unable to load cffi-libffi in Debian jessie

Hello,
I'm new to cffi and Lisp in general. I've been having a lot of trouble getting cffi to work with passing structs using libffi. I fussed with it for weeks and decided to wait until I upgraded Debian to jessie to see if that helped. Now I can't even load cffi-libffi. :(

Failed to find the TRUENAME of /usr/share/common-lisp/source/cl-cffi/libffi/init.lisp:
  No such file or directory

Before that there are a bunch of warnings like this:

compiling #<STATIC-FILE "alexandria" "LICENCE"> completed without its input file #P"/usr/share/common-lisp/source/alexandria/LICENCE"

The code:

#!/usr/bin/sbcl --script

(require "asdf")

(asdf:load-system :cffi)
(asdf:load-system :cffi-libffi)

This could just be a missing package, but I have everything I can think of. I searched the Debian respository for /usr/share/common-lisp/source/cl-cffi/libffi/init.lisp and none of them provide it. Here are my package versions:

sbcl 2:1.2.4-2
cl-cffi 1:0.14.0-1
cl-asdf 2:3.1.4-1
libffi6 3.1-2+b2
libffi-dev 3.1-2+b2

Can anyone help me solve this?

Marshall
Huang, Ying | 11 Apr 02:50 2015

[Resend] How to free the array element

Hi, All,

I found the format of my original email is not correct (sent with web
mail), and I got no response for some while, so I resend it in Emacs,
hopes it works better this time.

I am working on cl-gobject-introspection
(https://github.com/andy128k/cl-gobject-introspection), a common lisp
gobject introspection binding. I was trying to use extended foreign type
system of CFFI to implement some foreign memory operations. I have some
questions about that.

I need to manipulate foreign array. I tried to define an extended
foreign array type because there are some features that are lacking in
foreign-array-type of cffi. I can access/assign element of foreign array
with cffi:mem-ref and (setf cffi:mem-ref). But I don't know how to free
element of foreign array (the element type can be aggregated).

Then I checked foreign-array-type implementation of CFFI, and found
there appears no way to free translated element of array with that type
too. For example:

(defvar *string-array* (cffi:convert-to-foreign #("a" "b" "c")
                        '(:array :string 3)))

(cffi:free-foreign-object *string-array* '(:array :string 3) t)

The translated foreign objects corresponding to string "a", "b" and "c"
are not freed if my understanding were correct.

I think if there is a cffi:mem-free (I know, the name is bad) like
cffi:mem-ref, may be this can be resolved.

(defun mem-free (ptr type param &optional (offset 0))
  (let* ((parsed-type (parse-type type))
         (ctype (canonicalize parsed-type)))
    (if (aggregatep parsed-type)
        (free-translated-object (inc-pointer ptr offset)
                                parsed-type param)
        (free-translated-object (%mem-ref ptr ctype offset)
                                parsed-type param))))

I think you guys may have better idea about how to resolve the question.

Best Regards,
Huang, Ying

Huang, Ying | 1 Apr 14:44 2015

How to free the array element

I am working on cl-gobject-introspection (https://github.com/andy128k/cl-gobject-introspection), a common lisp gobject introspection binding.  I am trying to use extended foreign type system of CFFI to implement foreign memory operations.  I have some questions about that.

I need to manipulate foreign array.  I tried to define an extended foreign array type because there is some features that is lacking in foreign-array-type.  I can access/assign element of foreign array with cffi:mem-ref and setf.  But I don't know how to free element of foreign array (the element type can be aggregated).

Then I checked foreign-array-type implementation of CFFI, and found there appears no way to free translated element of array too.  For example:

(defvar *string-array* (cffi:convert-to-foreign #("a" "b" "c") '(:array :string 3)))
(cffi:free-foreign-object *string-array* '(:array :string 3) t)

The foreign memory corresponding to string "a", "b" and "c" is not freed if my understanding were correct.

I think if there is something like cffi:mem-free like cffi:mem-ref, may be this can be resolved.  It can be something like.

(defun mem-free (ptr type param &optional (offset 0))
  (let* ((parsed-type (parse-type type))
         (ctype (canonicalize parsed-type)))
    (if (aggregatep parsed-type)
        (free-translated-object (inc-pointer ptr offset) parsed-type param)
        (free-translated-object (%mem-ref ptr ctype offset) parsed-type param))))

I think you guys may have better idea about how to resolve the question.

Best Regards,
Huang, Ying



Lucien Pullen | 25 Mar 19:26 2015
Picon

64-bit stat and statfs on Mac

Greetings list.

I'm running into a bit of a conundrum.  I'm calling into stat(2) and
statfs(2) on Mac operating systems and get back the old 32-bit structure
instead of the new 64-bit structure.

If I compile a test program in C I get the 64-bit structure with just
<sys/mount.h> included.  When I use DEFCFUN I get the 32-bit structure.
Same for <sys/stat.h>.  I'm working around it currently using #+, but
I'd like some help understanding what's going on so I can do a proper
implementation.

I read in the include files and man pages that the *64 functions are
temporary things while old code gets updated and that users should never
actually call them.  In the include file they are different functions
(see below for statfs), but there is some preprocessor magic happening.
There's a pair of defines _DARWIN_USE_64_BIT_INODE and
_DARWIN_NO_64_BIT_INODE that you can set before doing the include to set
the default behavior, but CFFI doesn't do grovelling for function
definitions.

--8<---------------cut here---------------start------------->8---
int	statfs(const char *, struct statfs *) __DARWIN_INODE64(statfs);
#if !__DARWIN_ONLY_64_BIT_INO_T
int	statfs64(const char *, struct statfs64 *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
#endif /* !__DARWIN_ONLY_64_BIT_INO_T */
--8<---------------cut here---------------end--------------->8---

It just caused me a bunch of confusion because I was getting junk out of
CONVERT-FROM-FOREIGN with :INODE64 in *FEATURES*, so now that I've
gotten it to work I'm curious.

Mirko Vukovic | 9 Feb 21:50 2015
Picon

foreign-free causes stack dump (on CCL) after a repeated calls

Hello,

I am running 64-bit CCL 1.10 on Windows 7.  I'm writing an interface to a National Instruments library (dll)
The library was downloaded from the NI site.  It was compiled using Microsofts C++ compiler.

I get a stack dump when a pointer is being freed using foreign-free.  This error occurs not in a fresh lisp
session, but after a second or third call to the same function (with same arguments).

One more detail: the library is used to access data in files in NI's TDMS format.  This error does not
seem to happen on all files that I am trying to access, only some of them.

I don't have much experience in cross-language library interface building, and I am wondering if I am making
some kind of mistake.  I am hoping for pointers on how to debug this further.

I define a pointer of type :uint to access results of a call to a library function that places them into an
unsigned int variable.  I then retrieve the value using using mem-ref, and the free the pointer. 
This is where the stack dump happens.

What follows is the defcfun, and the lisp function.  I mark with *** the pointer, and the relevant variable
definitions that pertain to it:

The C-function interface (with the C-documentation included) is
(defcfun (ddc-get-num-channel-group-properties "DDC_GetNumChannelGroupProperties")
    ddc-code
  "
This function will get numberOfProperites (via a pointer)

int DDC_GetNumChannelGroupProperties (DDCChannelGroupHandle channelGroup,
                                      unsigned int *numberOfProperties); *******"
  (group-handle group-handle) ;; group-handle is define to be a pointer type
  (num-channel-group-properties :pointer)) ;;*******

The pointer issue arises with the second variable num-channel-group-properties.

The lisp code where the error occurs is below (relevant lines highlighted with ***).

(defun get-num-channel-group-properties (group-handle*)
  "Get number of file properties

FILE-HANDLE* is a pointer to the file handle"
;;  (trace foreign-alloc)
  (let ((number-of-properties
       (let ((number-of-properties* (foreign-alloc :uint))) ;;******
         (print 'allocated-pointer)
         (print number-of-properties*)
         (ddc-get-num-channel-group-properties group-handle*
                           number-of-properties*)
         (print 'done-with-ddc)
         (prog2
         (print 'acessing-number-of-properties)
         (mem-ref number-of-properties* :uint) ;; ********
           (print 'freeing-pointer)
           (foreign-free number-of-properties*) ;; ********
           (print 'freed-pointer)))))
  ;;  (untrace foreign-alloc)
    (print 'ready-to-return-with-value)
    number-of-properties))

The traceback is:

ALLOCATED-POINTER
#<A Foreign Pointer #x5FFC70>
DONE-WITH-DDC
ACESSING-NUMBER-OF-PROPERTIES
FREEING-POINTER
 1> Calling (FOREIGN-FREE #<A Foreign Pointer #x5FFC70>)

and the debugger traceback is

(#x0000000026479810) #x00000000000F532C : #<Function FREE #x00000001000F51BF> + 365
(#x0000000026479840) #x0000000001491314 : #<Function (TRACED FOREIGN-FREE) #x000000210149109F> + 629
(#x0000000026479888) #x000000000139DE14 : #<Function GET-NUM-CHANNEL-GROUP-PROPERTIES #x000000210139DCDF> + 309

So, to summarize:

I have created a pointer to access results of a library call.  Library accesses contents of files created with National
Instruments software.  Library is compiled with MS C++.

The pointer free crash occurs on the third call of the lisp function.  The first two calls (with same arguments)
run OK.

Thanks,

Mirko
_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
https://mailman.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel

Gmane