[Openmcl-devel] FFI help...get address to element in structure

Gary Byers gb at clozure.com
Sat Sep 19 07:01:49 UTC 2009


Two unrelated points (maybe three.  Hmm.  Some of them may be related.
Ahem.)

Some points:

- If a structure has a non-scalar field (e.g., an array/strucure/union),
   then

   (pref ptr :struct_type.non_scalar_field_name)

   returns a pointer to that field; if the field is scalar, then PREF returns
   its value.

   It doesn't make sense to talk about the value of a non-scalar, but it
   does make sense to talk about either the value or address of a scalar.
   As Matt notes, there's nothing in CCL's FFI that does that for you,
   but something like:

   (field-address pointer accessor) ; syntax like (PREF pointer accessor)

   would be useful and easy to implement (as long as the field in question
   was byte-addressable - it's hard to talk about the address of a bitfield.)

- a signal mask is usually of type "sigset_t"; what a "sigset_t" is is
   platform-dependent (it's sometimes just a 32-bit integer, other times
   a small array of integers or bytes.  Depending on whether "sigset_t"
   is a scalar or aggregate type, PREF might already be doing the right
   thing.

- it'd take a while to explain what the issues are (they're mostly related
   to the GC), but there isn't really any support for user-defined signal
   handlers in CCL.  (If/when there is, you'd basically have to use that
   support rather than calling "sigaction" yourself.)

   Until that support exists ... well, I was going to say that you might
   be able to get away with a very simple handler that ran with all signals
   masked, but I'm not even sure if that handler would be able to cons
   safely.

   The constraints in this case don't have to do with the FFI, but with
   threads, the GC, and the way that they interact.

On Sat, 19 Sep 2009, R. Matthew Emerson wrote:

>
> On Sep 18, 2009, at 6:24 PM, Michael Kohout wrote:
>
>> Next week I'm doing a presentation to my local lisp user group on FFI
>> (CFFI and CCL's FFI).  My example is a simple network client and
>> server.
>>
>> Anyways, the code I'm writing requires me to get the address to a
>> field in a struct( &sa.sa_mask, where sa is a sigaction structure).
>>
>> Does CCL's ffi system allow me to get this without munging around
>> with the internal layout of the structure?  If so, how?
>
> I don't know if this qualifies as munging around, but maybe this
> example will help.
>
> ;; struct sigaction sa;
> ;; (sort of;  in ccl, sa is a macptr referencing a stack-allocated
> structure)
> (rlet ((sa (:struct sigaction)))
>   ;; sa.sa_mask = 999;
>   (setf (pref sa :sigaction.sa_mask) 999)
>   ;; char *p = &sa.sa_mask
>   (with-macptrs ((p (%inc-ptr sa (ccl::get-field-
> offset :sigaction.sa_mask))))
>     ;; return *(long *)p;
>     (%get-long p)))
>
> If you don't really need a pointer to the sa_mask field and just want
> to know what its contents are (or to set them), you can use (pref
> sa :sigaction.sa_mask).
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list