Welcome to the CHICKEN Scheme pasting service
cbtest pasted by alicemaz on Wed Jul 1 03:48:06 2020
(module cbtest () (import scheme) (import chicken.base) (import chicken.string) (import chicken.format) (import chicken.foreign) (import chicken.memory) (import chicken.memory.representation) (import dyn-vector) (import object-evict) (define object->address (compose pointer->address object->pointer)) (define address->object (compose pointer->object address->pointer)) (define cb-vec (make-dynvector 16 #f)) (define-external cb_vec scheme-object (record-instance-slot cb-vec 0)) (define (register-cb! fn . args) (let* ((i (dynvector-index not cb-vec)) (argp (object->address (object-evict args)))) (dynvector-set! cb-vec (or i (dynvector-length cb-vec)) `(,fn . ,argp)))) (define cb-wrapper (foreign-safe-lambda* void ((c-pointer i)) #<<EOM C_word f_a = C_block_item(cb_vec, *(int *)i); C_save(C_u_i_cdr(f_a)); C_callback(C_u_i_car(f_a), 1); EOM )) (define (testfn argp) (printf "maztest: ~S\n" (car (address->object argp)))) (define (main) (register-cb! testfn "hi") (let-location ((i int 0)) (cb-wrapper #$i)) (exit 0)) (main) ) ; alice@bellona:~/work/misc/cbtest % pontiff run ; running cbtest... ; maztest: "hi"
Simple callback example pasted by sjamaan on Wed Jul 1 09:25:34 2020
(module cbtest ()
(import scheme)
(import chicken.base)
(import chicken.string)
(import chicken.format)
(import chicken.foreign)
(define callbacks (list)) 
(define (register-cb! fn) 
  (set! callbacks (cons fn callbacks)))
(define-external
  (cb_wrapper)
    void
     (for-each (lambda (cb) (cb)) callbacks))
(define (testfn argp)
  (printf "maztest: ~S\n" (car argp)))
(define (main)
  (register-cb! (lambda () (testfn '("hi"))))
  ((foreign-safe-lambda* void () "cb_wrapper();"))
  (exit 0))
(main)
)
cbtest2 added by alicemaz on Wed Jul 1 11:03:20 2020
(module cbtest ()
(import scheme)
(import chicken.base)
(import chicken.string)
(import chicken.format)
(import chicken.foreign)
(import chicken.memory)
(import object-evict)
; so this is a generic wrapper that converts a fn/arg pointer and calls one on the other
; if I stick a vector in the args then it can just setbang stuff in it between cycles ig
(define-external (cb_wrapper2 (c-pointer v)) void
  (let ((f/a (pointer->object v)))
       (apply (car f/a) (cdr f/a)))) 
; reexpose the name to scheme
(define-foreign-variable cb-wrapper2 (function void (c-pointer)) "cb_wrapper2")
; this sorta simulates nng-aio-alloc. ie, a scheme wrapper on a c function that accepts a c callback
; so this takes the cb_wrapper2 function and address of a pair of scheme function and args
; in theory if we can execute in here it'd work in an aio too
(define mk-aio (foreign-safe-lambda* void (((function void (c-pointer)) fn) (c-pointer arg)) "fn(arg);"))
; and then this simulates external interface
(define (create-aio fn . args) 
  (let ((f/a (object-evict (cons fn args))))
       (mk-aio cb-wrapper2 (object->pointer f/a)))) 
(define (testfn s n)
  (printf "maztest: ~S ~S\n" s n))
(define (main)
  (create-aio testfn "hi" 1) 
  (exit 0))
(main)
)