[gambit-list] Anyone else working in a schemey wrapper for c structs/unions/types?

Estevo euccastro at gmail.com
Wed Dec 25 02:53:56 EST 2013


>
>> > (define o (get-foreign-wrapper ...))  ; a will has been created for o,
>> which will delete the underlying C data
>> > (define t (make-table weak-values: #t))
>> > (table-set! t 'o o)
>> > (set! o #f)
>> > (##gc)
>>
>> At this point your foreign wrapper is not strongly reachable anymore.
>> The garbage collection has triggered your will, which has freed the C
>> object wrapped by o.  But you can still
>>
>> > (println (table-ref t 'o))
>>
>> And get an access to invalid memory or a segmentation fault.
>>
>
> Wait, what is returned by get-foreign-wrapper and are other references to
> it sticking around at that GC?
>

get-foreign-wrapper creates a foreign object with type (struct "something")
and attachs a will to it that calls (e.g.) foreign-release! on it when
executed.  A complete, working example follows:

; test-invalid-access.scm
;
; Compile with
;
; gsc -cc-options -g -exe test-invalid-access.scm
;
; Test with
;
; valgrind ./test-invalid-access
;
; (Or some other memory usage checker.)
;
; Comment out last line to see that the program would otherwise never
access
; invalid memory.

; BEGIN Library code

(c-declare "struct point {int x; int y;};")

(define (make-point x y)
  (let ((p ((c-lambda (int int)
                      (struct "point")
              "struct point *p = (struct
point*)___EXT(___alloc_rc)(sizeof(struct point));
               p->x = ___arg1;
               p->y = ___arg2;
               ___result_voidstar = p;")
            x
            y)))
    (make-will p
               (lambda (x)
                 (println "releasing " (point->string x))
                 (foreign-release! x)))
    p))

(define point-x
  (c-lambda ((struct "point"))
            int
    "___result = ((struct point*)___arg1_voidstar)->x;"))

(define point-y
  (c-lambda ((struct "point"))
            int
    "___result = ((struct point*)___arg1_voidstar)->y;"))

(define (point->string p)
  (string-append "point("
                 (number->string (point-x p))
                 ", "
                 (number->string (point-y p))
                 ")"))

; END library code; BEGIN user code

(define p (make-point 1 2))
(define t (make-table weak-values: #t))
(table-set! t 'p p)
(println "before releasing: " (point->string p))
(set! p #f)
(##gc)
(println "after releasing:")
; Comment out the following line and you get no invalid accesses.
(println (point->string (table-ref t 'p)))

; END of example
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20131225/28912d9b/attachment.htm>


More information about the Gambit-list mailing list