[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