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 destructor. 3. With my current code, I'm not getting any memory errors but I am getting weird values in the database.
For example....
With this binding, I don't get any memory errors but I do get nonsense values going into the database. Here's an example....
sqlite> select * from clinical_data; ˆ|Ñø·Ñø·IBUTE|ˆ|˜Â'ø|ˆ|˜Â'ø|Ñø·Ñø·IBUTE||
The values I'm passing in to get this are...
001, StudyEventOID, 1, FormOID, 1, PARTIAL, ALL ATTRIBUTE, ID.PD, 1959-12
Any ideas what's going on here?
Cheers, Andy
"Andy Chambers" achambers.home@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...
- If you specify the type as :string, does cffi pass it through as a
null terminated string?
Yes.
- 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.htm... are still accurate.
So the answer is "just what does `once the C library is finished with it' mean anyway?"
- With my current code, I'm not getting any memory errors but I am
getting weird values in the database.
ˆ|Ñø·Ñø·IBUTE|ˆ|˜Â'ø|ˆ|˜Â'ø|Ñø·Ñø·IBUTE||
Any ideas what's going on here?
See footnote ¹ on the page I linked above.
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.
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=t...
the cffi bindings were generated using verrazano.