[plt-scheme] Problem with FFI functions returning pointers to 'C' functions
I've revisited my problem, and I have got a little further
(in fact a solution I can work with).
On 12/09/07 10:10, Tim Brown wrote:
> A more concrete example is setting a signal(3C) call:
>
> (require (lib "foreign.ss"))
> (unsafe!)
> (define c-signal
> (get-ffi-obj "signal" #f (_fun _int (_fun _int -> _void) ->
> (_fun _int -> _void))))
> (c-signal 15 (lambda (f) #f))
>
> However, when I run this on: MzScheme v370 [3m]
> SunOS 5.10 x86 or even Linux
>
> I get the following error:
> ffi-call: expects type <non-null-cpointer> as 1st argument, given: #f;
> other arguments were: (#<ctype>) #<ctype>
This error is caused by the signal function returning a NULL pointer.
Since no signal handler is initially installed for 15 in this case,
a NULL is returned.
Why is the error reported by ffi-call, and not whatever it is that
objected to the #f in the first place?
Anyway, I am returning a _fpointer, and only casting it (with ptr-set)
to an (_fun _int -> _void) if it is (not #f).
Oh, and this is were I come across another problem... if I cast the
pointer to (_fun _int -> _void), I get a:
"Scheme->C: expects argument of type <int32>; given #<void>" when I
call it.
This seems to be a manifestation of the bug described in:
http://www.cs.brown.edu/pipermail/plt-scheme/2005-May/008797.html
"Questions about modules, compilation, namespaces, planet and ffi"
If I mis-declare these callback functions to be returning _int, and
ignore the results, I can get things to work as I wish.
Could someone comment on whether there is a better way to express the
following.
(require (lib "foreign.ss"))
(unsafe!)
(define signal-handler-ptr (_cprocedure (list _int) _int))
(define signal-handler-ptr/null _fpointer)
(define c-signal (get-ffi-obj "signal" #f
(_fun _int signal-handler-ptr -> signal-handler-ptr/null)))
(define old-signal-handler #f)
(set! old-signal-handler
(c-signal 15 (lambda (i) (printf "first set callback ~a~%" i) 0)))
(set! old-signal-handler
(c-signal 15
(lambda (i)
(printf "second set callback~%")
(if old-signal-handler
((ptr-ref old-signal-handler signal-handler-ptr) i))
0)))
I'm not actually using this for signal handling, I'm just using
this as a means to illustrate callbacks.
Regards,
Tim
--
Tim Brown <tim.brown at cityc.co.uk> | City Computing Limited |
T: +44 20 8770 2110 | City House, Sutton Park Road |
F: +44 20 8770 2130 | Sutton, Surrey, SM1 2AE, GB |
-----------------------------------------------------------------------|
BEAUTY: What's in your eye when you have a bee in your hand |
-----------------------------------------------------------------------'
City Computing Limited registered in London No. 1767817.
Registered Office: City House, Sutton Park Road, Sutton, Surrey, SM1 2AE
VAT number 372 8290 34.