chicken-users
[Top][All Lists]
Advanced

[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.

-- 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]