Calling mysql_real_escape_string using the PLT-Scheme Foreign Function Interface
using the PLT-Scheme-FFI, I want to call the C-function
unsigned long mysql_real_escape_string(MYSQL *con, char *to, const char *from, unsigned long length)
from a scheme procedure and continue using the resulting string 'to' inside the caller. The call of the scheme procedure would go like this:
(define-values (to) (escape-string con ??? from (+ (string-length from) 1)))
where con is a valid connection to a MySQL-DB and escape-string is defined by
(define escape-string (get-ffi-obj "mysql_real_escape_string" libmysql
(_fun (con to from length) ::
(con : _pointer)
(to : (_ptr io _byte))
(from : _string)
(length : _ulo开发者_开发知识库ng)
-> (res : _ulong)
-> (values out))))
The problem is, I have no idea what to pass for '???' when calling escape-string nor do I know whether the definition of escape-string is correct.
Any help would be appreciated.
Regards,
Ralf S.
In general, _ptr
arguments are used where the foreign (C) code expects a pointer, but you want to avoid dealing with a pointer on the Scheme side. For example, (_ptr o _int)
would be used when you have a foreign function that expects an integer pointer and sets it to some value (often called "an output pointer" hence the "o
"). The _fun
arranges for an allocation of a pointer, and will dereference it when the call is done -- but the thing that can be confusing is that you need to grab this value with a name or it will just be dropped. Here's an example for doing this:
(_fun [r : (_ptr o _int)] -> _void -> r)
You should read this as: pass a pointer to an integer to the foreign function, and make the resulting value available as r
. The foreign function returns void, but that's ignored and instead it returns the value of r
, effectively dereferencing the pointer. Note that since this is an output pointer, you don't need to specify an input value of it. For example, if that type is used for some foo
binding, then foo
would expect no arguments.
A (_ptr i _int)
is different: the resulting function would expect an integer, allocate a pointer when called and pass that pointer to the foreign function (so the C code still sees an int*
) then discard this pointer after the call. The purpose here is to make it easy to use such functions without doing the tedious allocation yourself. Note that in this case, this does correspond to an input to the resulting Scheme function, but does not correspond to a value that can be used later.
Finally, (_ptr io _int)
is a combination of the two: the Scheme function will expect an integer, will allocate a pointer and put the given integer in it, call the C function and hand it that pointer, then dereference it and give you the result. For example, if you have this C function:
void inc(int* p) { (*p)++; }
Then this would be a suitable Scheme definition for it:
(define inc
(get-ffi-obj 'inc "foo.so"
(_fun [r : (_ptr io _int)] -> _void -> r)))
Sorry about the format. When I clicked the submit button on the comment box it looked quite differently :-)
Anyway, here it is again:
... But what about the following C-function:
void setstring(char* str) { strcpy(str, "foo"); }
Is the following Scheme definition correct?
(define setstring
(get-ffi-obj 'setstring "foo.so"
(_fun [r : (_ptr io _byte)] -> void -> r)))
If the definition is OK, how do I call setstring from Scheme, such that I can proceed to work with the result r? IMO something like this
(define r (setstring ???))
(do-something-with-r ...
or this
(let ((r (setstring ???)))
(do-something-with-r ...
should work. However, I just don't know what to pass as argument ??? to setstring.
I figured it out. A suitable Scheme definition for the C-function
void setstring(char* str) { strcpy(str, "foo"); }
that is contained in the dynamic library 'lib.so' is
(define setstring
(get-ffi-obj 'setstring "lib.so"
(_fun (r : _u8vector) -> _void -> r))))
It can be called e.g. like this
> (setstring (make-u8vector 5))
which prints
> #"foo\0\0"
You may find one of these helpful:
- http://knauth.org/plt/mysql/mysqlclient/
- http://github.com/troelskn/mr-mysql
精彩评论