chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] FFI unsigned long pointer


From: Zbigniew
Subject: Re: [Chicken-users] FFI unsigned long pointer
Date: Wed, 27 Jul 2005 16:58:59 -0500

Toby, you might want to look at the hostinfo egg for examples of
passing vector data back to scheme from C.  In general there are a few
ways to accomplish what you want.  However, note that srfi-4 values
cannot be used as return types from foreign-lambda.

It is definitely possible to build an object with C_vector (or
C_bytevector, undocumented) and return it as a scheme-object.  You
will need to allocate the required memory from the stack with C_alloc,
and you must use foreign-primitive instead of foreign-lambda so that
the stack is not wiped out.  It's also possible to pre-allocate this
memory in Scheme (e.g., with make-byte-vector) and memcpy directly
into it in your C wrapper.  udp.egg does this, for example.

Personally, after rewriting the hostinfo interface several times, I
have come to prefer to do as much within scheme as possible.  In your
case, I might declare mysql_fetch_lengths as a foreign-lambda
returning a c-pointer, then use the c-pointer->byte-vector function in
hostinfo to convert to byte-vector, then convert that to a u32vector
(this shares the byte-vector memory, so virtually no overhead).  E.g.

(define mysql-fetch-lengths
  (let ((proc (foreign-lambda c-pointer "mysql_fetch_lengths" mysql-res))
    (lambda (result)
      (let ((len (mysql-result-length result))) ;; or however you get
the result length
        (byte-vector->u32vector (c-pointer->byte-vector (proc result) len))))))

(define (c-pointer->byte-vector ptr len)
  (let ((bv (make-byte-vector len))
        (memcpy (foreign-lambda bool "C_memcpy" byte-vector c-pointer integer)))
    (memcpy bv ptr len)
    bv))

But it totally depends on how raw you want the API to be, how you
intend to use it, and how the API works in general.  I've never used
it, and I don't know how the length is returned.  SWIG, by the way,
would probably wrap this in C_alloc / C_kontinue (foreign-primitive).

For advanced manipulation check out array0->string-vector [converts
null-terminated array of null-terminated strings to a scheme vector of
scheme strings] and array0->byte-vector [converts null-terminated
array of fixed-length IP addresses to a scheme vector of
byte-vectors].  These not only use C_alloc but build the container
vector manually, since each element is generated on the fly, and then
stores them with C_mutate.

Confused yet?
Zb

On 7/27/05, Toby Butzon <address@hidden> wrote:
> So, I'm playing with FFI (which is great, BTW :)). I'm writing some glue
> to use MySQL's C API from within Scheme (which I hope to submit as an
> egg soon...) and I've come across this:
> 
> unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
> 
> Now, I can find out before I call this function how long the returned
> array is going to be... I just don't know how to get that array back
> into Scheme.  Could it be done using one of the srfi-4 foreign type
> specifiers... Or, if not, perhaps I could write a C wrapper that calls
> mysql_fetch_lengths, builds a vector out of the result with C_vector,
> and returns that. (Then what? I tell foreign-lambda it's a scheme-object?)
> 
> Please forgive me if this has been answered already... There's similar
> stuff already in the archives, but it doesn't quite seem to answer my
> question (or maybe I'm just too dense... :-P).
> 
> Thanks!
> 
> --
> Toby Butzon
> 
> 
> 
> _______________________________________________
> Chicken-users mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/chicken-users
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]