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
On Mon, Sep 1, 2008 at 3:47 PM, Andy Chambers achambers.home@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).
Finally, through MEM-REF, we access our newly allocated memory and get the DB handle.
HTH