[plt-scheme] cpointer to an allocated cpointer

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Jan 13 18:57:05 EST 2007

On Jan 14, Hans Oesterholt-Dijkema wrote:
> Dear All,
> 
> Suppose I want to do the following using the FFI:
> 
> void *p;
> int r=sqlite3_open("file",&p);
> 
> p will be allocated using the library.
> 
> How can I do that using the FFI?

Say that you have this C file:

  #include <stdlib.h>
  int make_foo(int i, int *p) {
    *p = i;
    return 0;
  }

The input pointer is used only as a second return value.  The _ptr
type helps in doing the usual work of allocating a block to put the
answer in, then dereferencing it.  You use it like this:

  > (define make-foo
      (get-ffi-obj "make_foo" "x.so"
                   (_fun _int [p : (_ptr o _int)] -> (r : _int)
                         -> (values r p))))
  > (make-foo 123)
  0
  123

the (_ptr o _int) is an `output pointer' (there are a few common
notations for these things in various IDLs), the `p :' binds it to a
name so you can grab that value and return whatever you want (multiple
values in this example).

Your case looks similar, except that you have a pointer to a pointer.
I'm changing the C file to:

  #include <stdlib.h>
  int make_foo(int i, int **p) {
    *p = malloc(sizeof(int));
    **p = i;
    return 0;
  }
  int foo2int(int *p) {
    return *p;
  }

and:

  > (require (lib "foreign.ss"))
  > (unsafe!)
  > (define make-foo
      (get-ffi-obj "make_foo" "x.so"
                   (_fun _int [p : (_ptr o _pointer)] -> _int -> p)))
  > (define foo->int (get-ffi-obj "foo2int" "x.so" (_fun _pointer -> _int)))
  > (define x (make-foo 123))
  > x
  #<cpointer>
  > (ptr-ref x _int)
  123
  > (foo->int x)
  123

If you're the one who should free the resulting block of memory, then
you should use a finalizer -- I just added some examples of doing that
correctly a few days ago (section 2.3.1).

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the users mailing list.