[plt-scheme] foreign.ss: callbacks in cstructs?

From: Jon Rafkind (workmin at ccs.neu.edu)
Date: Tue May 15 23:15:28 EDT 2007

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..


Posted on the users mailing list.