[plt-scheme] cpointer to an allocated cpointer
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!