Re: FLI pointers
On Wednesday 23 May 2007 8:41 am, Nico de Jager wrote:
> Hi
>
> I am confused about whether FLI pointers types (the pointer type itself,
> not that what the pointer points to) are immediate or aggregate types.
No one else has answered thus far, so I will give you my guess - but it is
only a guess.
Maybe you can figure out how to test my guess...
> (setq point1 (fli:allocate-foreign-object :type :char))
> (setq point2 (fli:copy-pointer point1))
> (fli:free-foreign-object point1)
I tried something like this, but I added another pointer - point3 which is
a '(:pointer :char) - a pointer to a pointer to a char.
I used (setf (fli:dereference point3) point1).
I used the inspector to look at point3.
Then I deallocated point3 and looked at it with the inspector. Point3 still
existed, but its fields were cleared.
So, I conclude that pointers are immediate types. The mis-wording in the docs
is trying to say that if a pointer points to an aggregate type, then the
thing pointed to by the pointer is indeed an aggregate type.
This is all exacerbated by C's squishy semantics - esp. arrays vs. structs
passed as parameters - and Lispworks' desire to make the FLI interface
easy-to-use.
> (fli:with-coerced-pointer (temp) array-obj
> ...)
>
> (let ((temp (fli:copy-pointer array-obj)))
> ...)
With-coerced-pointer is a C "cast". FLI pointers are objects that carry the
target type around inside them. To get C's "cast" behaviour, you have to
temporarily change the pointer's idea of what it's target type is. C does
this at compile time. FLI creates actual run-time objects, so you need to
tinker with their idea of type - the best choice is to clone the pointer and
futz with the cloned pointer's type field.
>
> If not, please answer the following:
>
> (setf array-obj
> (fli:allocate-foreign-object :type :int
>
> :nelems 10
> :initial-contents '(0 1 2 3 4 5 6 7 8 9)))
>
> (fli:with-coerced-pointer (temp) array-obj
> (dotimes (x 10)
> (print (fli:dereference temp))
> (fli:incf-pointer temp)))
>
> Can I now still use array-obj after these expressions have been
> evaluated or has it's memory been freed? with-coerced-pointer does not
> create a copy of what is being pointed to (I have tested this), does it?
Correct. Array-obj is an object (struct / whatever).
FLI:allocate-foreign-object creates two objects - the foreign object and the
pointer object.
FLI:with-coerced-pointer creates a copy of the pointer object (and changes its
type field).
At this point, there are two pointer objects (temp and array-obj) and one
array object (unnamed).
When the temp object disappears, the array-obj pointer object remains and so
does the actual 10-element unnamed array object.
Simply try out the code you've written. Use the inspector.
>
> Or does the documentation for with-coerced-pointer apply to the pointer
> and not what the pointer points to? E.g.:
>
> (setq point1 (fli:allocate-foreign-object :type :char))
> (setq point2 (fli:copy-pointer point1))
> (fli:free-foreign-object point1)
>
> Does point2 now still consume memory that have to be freed (as
> with-coerced-pointer would have automatically freed it)? If so, how do I
> free it as free-foreign-object frees what is being pointed to, not the
> pointer, which I suspect is an immediate type and automatically freed by
> GC, right?
Yes, that's my guess, too. The "memory" consumed by a pointer object is
memory within GC-able space. The "memory" consumed by aggregate objects is
not in GC space. Deep voodoo magic within FLI tracks whether the objects are
in GC space or non-GC space. If you deallocate a GC space object - i.e. an
immediate object - FLI simply clears the pointer's fields, then lets the GC
clean up some time in the future.
If my guess turns out to be wrong - let me know!
pt