Andy Chambers | 1 Sep 16:47 2008

Double pointers

Hi,

Please excuse the poor use of terminology in the following message.
I'm stabbing around in the dark when
it comes to C.  I'll need to get a textbook someday and learn it properly.

How do you pass a "double pointer" to a C function.  For example,
here's the signature for sqlite's open

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);

I'd like to define a cffi function that lets me call this and keep a
handle on the ppDb object that gets
created as a result.

I've tried various combinations of (foreign-alloc ..) and
(null-pointer) but always got a memory exception
when trying to use the handle in another function.

The sqlite stuff has lots of these functions that modify input
parameters and return error codes
rather than returning some opaque object like the CFFI example does.

Cheers,
Andy
Luís Oliveira | 1 Sep 17:31 2008
Picon

Re: Double pointers

On Mon, Sep 1, 2008 at 3:47 PM, Andy Chambers
<achambers.home <at> googlemail.com> wrote:

> int sqlite3_open(
>  const char *filename,   /* Database filename (UTF-8) */
>  sqlite3 **ppDb          /* OUT: SQLite db handle */
> );

Let's start by declaring this function:

    (defcfun ("sqlite3_open" %sqlite3-open) :int
      (filename :string)
      (db :pointer))

> I'd like to define a cffi function that lets me call this and keep a
> handle on the ppDb object that gets
> created as a result.

  (defun sqlite3-open (filename)
    "Open FILENAME and return a handle to the DB."
    (with-foreign-object (db :pointer)
      (%sqlite-open filename db) ; XXX: do error checking here...
      (mem-ref db :pointer)))

That WITH-FOREIGN-OBJECT form allocates enough memory to hold a
pointer. And the value of DB is a pointer to that newly allocated
memory. We pass that to sqlite3_open() which will fill that memory
with the DB handle (which is a pointer, i.e., an address that points
to some opaque SQLite structure).

(Continue reading)

Kalyanov Dmitry | 10 Sep 20:22 2008
Picon

Library specs with T are ignored

Hello, cffi-devel!

I have found a case when cffi behaves not as documented.
The documentation in page for define-foreign-library says about load-clauses 
list that "Finally, if feature is t, this load-clause is picked 
unconditionally."

But the load-clause with feature set to T is ignored, because function 
%foreign-library-spec uses alexandria:featurep, which does consider T to be 
feature.

This patch should fix this: to return the load-clause that has feature set to 
T.

Test case:
(define-foreign-library libgraphan-wrap
  (t (:default "libgraphan-wrap")))

(equal
  (%foreign-library-spec (get-foreign-library 'libgraphan-wrap))
  (t (:default "libgraphan-wrap")))
=>
 T
Attachment (cffi-spec.patch): text/x-diff, 479 bytes
_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
(Continue reading)

Kalyanov Dmitry | 10 Sep 20:40 2008
Picon

Library specs with T are ignored

Hello, cffi-devel!

Sorry, last message was messed by gpg.

I have found a case when cffi behaves not as documented.
The documentation in page for define-foreign-library says about load-clauses 
list that "Finally, if feature is t, this load-clause is picked 
unconditionally."

But the load-clause with feature set to T is ignored, because function 
%foreign-library-spec uses alexandria:featurep, which does consider T to be 
feature.

This patch should fix this: to return the load-clause that has feature set to 
T.

Test case:
(define-foreign-library libgraphan-wrap
  (t (:default "libgraphan-wrap")))

(equal
  (%foreign-library-spec (get-foreign-library 'libgraphan-wrap))
  (t (:default "libgraphan-wrap")))
=>
 T
Attachment (cffi-spec.patch): text/x-diff, 469 bytes
_______________________________________________
cffi-devel mailing list
(Continue reading)

Andy Chambers | 10 Sep 23:35 2008

foreign strings

Hi,

I'm still plugging away on sqlite

I've got a problem creating a binding for the following function

int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));

I tried the following....

(defcfun ("sqlite3_bind_text" %sqlite-bind-text) :int
  (stmt :pointer)
  (index :int)
  (value :string)
  (len :int)
  ;; not really an int but cffi takes care of this for us
  (destructor :int))

Everything is pretty straightforward apart from the last two
parameters.  Length is supposed to be the length of the value being
passed in (or -1 if the value is null terminated).
The destructor is supposed to be a function that frees the memory
required by `value' after sqlite is finished with it.  For destructor,
you can use the special value 0 if the memory
is in "unmanaged" space.  So I have a few questions...

1. If you specify the type as :string, does cffi pass it through as a
null terminated string?
2. Does cffi take care of freeing a string once the C library is
finished with it or should I define a callback to use for the
(Continue reading)

Stephen Compall | 11 Sep 00:00 2008
Picon

Re: foreign strings

"Andy Chambers" <achambers.home <at> googlemail.com> writes:
>   (value :string)
>   (len :int)
>   ;; not really an int but cffi takes care of this for us
>   (destructor :int))
>
> Everything is pretty straightforward apart from the last two
> parameters.  Length is supposed to be the length of the value being
> passed in (or -1 if the value is null terminated).
> The destructor is supposed to be a function that frees the memory
> required by `value' after sqlite is finished with it.  For destructor,
> you can use the special value 0 if the memory
> is in "unmanaged" space.  So I have a few questions...
>
> 1. If you specify the type as :string, does cffi pass it through as a
> null terminated string?

Yes.

> 2. Does cffi take care of freeing a string once the C library is
> finished with it or should I define a callback to use for the
> destructor.

The semantics described in
http://common-lisp.net/project/cffi/manual/html_node/Tutorial_002dMemory.html
are still accurate.

So the answer is "just what does `once the C library is finished with
it' mean anyway?"

(Continue reading)

Stelian Ionescu | 11 Sep 00:20 2008
Picon

Re: foreign strings

On Wed, 2008-09-10 at 22:35 +0100, Andy Chambers wrote:
> Everything is pretty straightforward apart from the last two
> parameters.  Length is supposed to be the length of the value being
> passed in (or -1 if the value is null terminated).
> The destructor is supposed to be a function that frees the memory
> required by `value' after sqlite is finished with it.  For destructor,
> you can use the special value 0 if the memory
> is in "unmanaged" space.  So I have a few questions...

from the sqlite documentation:
The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
string after SQLite has finished with it. If the fifth argument is the
special value SQLITE_STATIC, then SQLite assumes that the information is
in static, unmanaged space and does not need to be freed. If the fifth
argument has the value SQLITE_TRANSIENT, then SQLite makes its own
private copy of the data immediately, before the sqlite3_bind_*()
routine returns.

You're passing 0 as fifth parameter, which is SQLITE_STATIC, but that's
only for static data, while CFFI C-strings are dynamically allocated.
Use SQLITE_TRANSIENT instead.

--

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

_______________________________________________
(Continue reading)

Attila Lendvai | 11 Sep 09:39 2008
Picon

Re: foreign strings

> I'm still plugging away on sqlite

fyi, here's a working sqlite backend for cl-rdbms:
http://common-lisp.net/cgi-bin/darcsweb/darcsweb.cgi?r=cl-rdbms-cl-rdbms;a=tree;f=/sqlite

the cffi bindings were generated using verrazano.

--

-- 
 attila
Luís Oliveira | 12 Sep 16:07 2008
Picon

Re: Library specs with T are ignored

On Wed, Sep 10, 2008 at 7:22 PM, Kalyanov Dmitry
<kalyanov.dmitry <at> gmail.com> wrote:

> This patch should fix this: to return the load-clause that has feature set to
> T.

Thanks. Applied and released as 0.10.2.

--

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Luis Oliveira | 13 Sep 06:00 2008
Picon

New patches: 12-Sep-2008


Fri Sep 12 09:35:00 EDT 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  tagged 0.10.2

Fri Sep 12 09:34:56 EDT 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * update cffi.asd for version 0.10.2

    M ./cffi.asd -1 +1

Fri Sep 12 09:34:24 EDT 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * TODO cleanup

    M ./TODO -2

Fri Sep 12 09:33:50 EDT 2008  Luis Oliveira <loliveira <at> common-lisp.net>
  * Fix handling of the T clause in DEFINE-FOREIGN-LIBRARY

  - Added regression test: LIBRARY.T-CLAUSE.

  Bug report and initial patch courtesy of Kalyanov Dmitry.

    M ./src/libraries.lisp -1 +4
    M ./tests/misc.lisp +13

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

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


Gmane