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

Michael Kohout mwkohout at gmail.com
Sun Sep 20 19:36:55 PDT 2009


Thanks for the tips, guys.  I've got one more (really trivial) problem:
 I've got a small dylib to paper over FFI issues with some c macros I
need: FD_ZERO,
FD_ISSET and family.
Anyways-I load the dylib:
(open-shared-library
"/Users/development/Documents/networkServer/build/Release/libnetworkServer.dylib")

and I can call the function when I use external-call directly:
(defparameter *fd-set* (ccl::make-gcable-record fd_set))
(external-call "mike_fd_zero" (:* (:STRUCT :FD_SET)) *fd-set* :void)

but when I load the interface directory I've set up, it doesn't find the
method:
(use-interface-dir :network-helper )
#<INTERFACE-DIR :NETWORK-HELPER #P"network-helper/" #x3000416D290D>
CL-USER> #_?mike_fd_zero
NIL

Does the dylib have to be in a certain place for the runtime to pick it up
or something?  Am I missing a simple step?  Could I be messing something up
when generating the ffi/cdb files?  Here's the meat of my populate.sh file:

CFLAGS="-m64 -fobjc-abi-version=1 -Wno-endif-labels
-mmacosx-version-min=10.4.8";export CFLAGS
/Users/development/Applications/ffigen4/bin/h-to-ffi.sh
/Users/development/Applications/ccl-head/darwin-x86-headers64/network-helper/C/interface.h

FYI I'm running this on the x86_64 build of CCL.

Anyways, thanks for the help so far!
Mike Kohout


On Sat, Sep 19, 2009 at 2:01 AM, Gary Byers <gb at clozure.com> wrote:

> 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
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20090920/73d8fc90/attachment.htm>


More information about the Openmcl-devel mailing list