[plt-scheme] FFI: problem with define-cpointer-type

From: Eli Barzilay (eli at barzilay.org)
Date: Thu Sep 25 15:11:24 EDT 2008

On Sep 25, Sam Phillips wrote:
> Hi,
> I'm having problems using a type defined by define-cpointer-type as
> an argument to a foreign function.  Whenever I call out I get:
>   Scheme->C: expects argument of type <pointer>; given #<my-type>
> Basically the code involved looks like:
> ;;; there is actually more in this struct...
> (define-struct my-type (ptr))
> (define-cpointer-type _my-type-ptr #f
>   (lambda (v)
>     (if (my-type? v)
>       (my-type-ptr v)
>       (error "cannot coerce to _my-type-ptr")))
>   (lambda (ptr)
>     (if ptr
>       (make-my-type ptr)
>       (error "got null"))))
> (define my-type-maker
>   (get-ffi-obj "my_type_maker" lib
>     (_fun -> (ret : _my-type-ptr/null)
>           -> (if ret ret (error "got null")))))
> (define my-type-operation
>   (get-ffi-obj "my_type_operation" lib
>     (_fun _my-type-ptr -> _int)))
> (define a (my-type-maker)) ; a is a proper my-type struct
> (my-type-operation a)      ; throws above error

I don't see anything wrong here offhand, but it looks like some
context is missing.  Specifically, the question is what exactly does
`my-type-maker' return -- what's the contents of it's `ptr' field.
You can also just add a printf to the Scheme->C part of your
definition to see that it gets to run, and check out its input/output.

> I can't seem to find any examples in Planet or core collects that
> use define-cpointer-type in this way.  The closest thing I found was
> in the examples magick.ss in defining the _PixelIterator type, and
> it uses a ctype and not a cpointer.

The main difference is that ctype is the basic functionality, where
you translate some value to some other value that is "closer" to being
translatable to C.  For example, you build a _foo type as an extension
of _int by providing functions to translate from some value to an
integer and back.  The cpointer thing is similar, but deal with the
extra bookkeeping that is needed to deal with null pointers and

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

Posted on the users mailing list.