[plt-scheme] foreign.ss: callbacks in cstructs?
Jim Meier wrote:
> Subversions libsvn_client library stores several common callback
> functions in a context structure; it's this context structure that is
> passed to the library functions, rather than the callback itself.
> Unfortunately, when I attempt to set a callback field to a scheme
> procedure, I get the error:
>
> ptr-set!: setting fpointer value with extra arguments
>
> I've tracked this down to src/foreign/foreign.ssc line 1318, in the
> definition of ptr-set!. It seems to be checking that callers aren't
> using offsets/indexes with function pointers; unfortunately, offsets
> are rather important for struct field access. A similar check is done
> in ptr-ref on line 1275.
>
It does seem strange that the make-TYPE code wants to do
(ptr-set! block stype 'abs offset slot)
but the C part only allows 4 arguments, I don't see a problem with
bumping the check on argc upto 4 but Eli or Matthew would know better.
> My subversion wrapper is rather large, but here's a representative
> example of how I'm going about this:
>
> (require (lib "foreign.ss")) (unsafe!)
>
> (define _callback_t
> (_fun (opaque_baton : _pointer) -> _int))
>
> (define-cstruct _struct_t
> ((optional-callback _callback_t)
> (optional-opaque-baton _pointer)))
>
> (define (my-callback baton)
> (display "Hello!") (newline))
>
> (define struct-instance (make-struct_t 1 2 my-callback #f))
> (set-struct_t-optional-callback! struct-instance #f)
> (display (struct_t-optional-callback struct-instance)) (newline)
I knew I did something similar at one point.. in my sdl bindings there
is an SDL-RWOps thing that is a table of functions but all the functions
are set within the C code so that doesn't help. It seems like you would
never really use (make-struct_t ...) anyway since you need to use
svn_client_create_context to get a svn_client_ctx_t out. I don't think
you still need ptr-set! if this is the case.
(defsvn svn-client-create-context (f : (_ptr o _svn-ctx-pointer))
pool-pointer) -> _error-pointer -> f)
(define (my-context (svn-client-create-context
(get-a-pool-from-somewhere)))))
(set-svn-ctx-log-msg-func! my-context _svn-ctx (lambda () ...))
All of this being completely untested of course..