[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