[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] FFI: Safe referencing and allocation of Scheme objec
From: |
Category 5 |
Subject: |
Re: [Chicken-users] FFI: Safe referencing and allocation of Scheme objects from C |
Date: |
Mon, 10 Nov 2003 15:04:19 +0000 |
User-agent: |
Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (berkeley-unix) |
felix <address@hidden> writes:
>>> Right. One way to address is is to use C_gc_protect() inside the body
>>> of `foo':
>>>
>>> #<<EOF
>>> /* Warning: untested! */
>>> C_word *data[ 1 ];
>>> int result;
>>> data[ 0 ] = &c;
>>> C_gc_protect(data, 1);
>>> result = black_box(...);
>>> C_gc_unprotect(1);
>>> return(result);
>>> EOF
>>
>> I have just tried this and the result is strange. The callback function
>> is called twice from black_box successfully, but the third time it's
>> called the assertion fails (the pointer is no longer pointing to the
>> procedure object). The code matches your example exactly.
>
> Hm. Strange, indeed. You have changed the type-declaration in
> `scheme_callback_func' to `scheme-object' for the assed data ("c"),
> right?
Nope, it looks like this:
(define-external (scheme_callback_func ((c-pointer unsigned-char) x))
void
(let ((p (pointer->object x)))
(assert (procedure? p))
(p ...)))
The calling function expects it to take an (unsigned char *), so
changing the declaration causes warnings. However, I went ahead and
tried changing it to:
(define-external (scheme_callback_func (scheme-object x))
void
(let ((p x))
(assert (procedure? p))
(p ...)))
It didn't help, though (runs once and then x turns into something that
when printed causes an "Error: unprintable non-immediate object
encountered").
>> Well, the Data Representation section of the manual says:
>>
>> procedures: special vector object (type bits C_CLOSURE_TYPE). The
>> first slot contains a pointer to a compiled C function.
>
> Well, that is really not clear enough. A procedure has 1 or more data
> slots, containing the free variables of the closure (if any). You can
> use C_header_size() to obtain the number of slots (excluding the
> header).
Ah! Okay, great. In any case, for all my tests the passed procedure
has no free variables, so C_header_size returns 1.
I also played around with the C_alloc_in_heap case a little more. The
call to that function itself succeeds and returns a pointer that looks
good; the fireworks start when the callback function is called. The
process immediately begins spinning, using 100% CPU. I can get a print
from the callback function to come through, but as soon as it tries to
call the procedure passed in as x above, it goes into never-never land;
not even a print at the beginning of the-procedure-x-points-to comes
through.
Very odd, especially since just replacing C_alloc_in_heap with malloc
makes everything run happily.
--