[Openmcl-devel] Accessing foreign #define'd constants
David Steuber
david at david-steuber.com
Wed Dec 22 18:47:24 PST 2004
On Dec 22, 2004, at 7:13 PM, Gary Byers wrote:
> Here's a little-known (perhaps because it's undocumented ...) fact:
> if the reader token that follows #$ is a quoted string of length 4,
> #$ produces an integer constant out of the char-codes, so:
>
> Welcome to OpenMCL Version (Beta: Darwin) 0.14.2-p1!
> ? #$"ctrl"
> 1668575852
> ? (format t "#x~x" *)
> #x6374726C
>
> In most cases, #$ can be used to reference constants that were defined
> with
>
> #define <name> <expression>
This is really cool and should be documented. I'm going to try it out
when my callback is working (that is, when I see it do something in
response to a button click). It will save having to explain in a
comment where some largish fixnum I am using in a defconstant form came
from.
> whether or not this works generally has to do with how complicated the
> C code in <expression> is. There's no requirement that the right-hand
> part of the #define - what I'm calling the <expression> - is even well-
> formed C code. If it looks like it is, OpenMCL's interface translator
> will try to parse and evaluate it; it's able to do a fairly good job
> of this in practice, but undoubtedly misses some things. It -does-
> try to catch cases like:
>
> #define FOO 1
> #define BAR (FOO + 17)
>
> and will make multiple passes to try to resolve forward references
> like
>
> #define BAR (FOO + 17)
> #define FOO 1
>
> C macros can also take parameters, as in:
>
> #define MAX(a,b) (a) > (b) ? (a) : (b)
>
> The interface translator ... um, assumes that this is some sort of
> irritating line noise and skips over it (trying to translate arbitrary
> parameterized C macros into "equivalent" Lisp macros is a hard
> problem).
>
> Summary:
> The interface translator should do a very good job of making constants
> defined as part of a C enumeration available to #$, and should catch
> a lot of cases where constants are defined via '#define <name> <expr>';
> its success in doing so generally depends on how much sense it can
> make out of <expr>.
>
> I'd be curious about cases where #$ doesn't find things; it's been a
> while since I checked, but I think of the translator's miss rate as
> being pretty low. (It's certainly possible that the Carbon headers
> use C idioms that the translator doesn't understand, and - depending
> on what they are - it might be possible to make it understand them.)
>
>
>>
>> Bottom line though is when you are using FFI to call into C (and
>> having
>> C call back!), it really does help to know some C.
>
> That's certainly true. I -think- that it's true that the total number
> of idioms you have to learn in order to translate a C example program
> into OpenMCL's FFI is fairly small, but the learning curve could
> probably
> be made less steep with a few examples.
I'm learning OpenMCL's FFI interface concurrently with Carbon. I have
been all over the FFI docs and also looking into ccl/lib/macros.lisp
for how to do things (like doing the equivalent of sizeof(HICommand)
which I translated into (ccl::%foreign-type-or-record-size :<HIC>ommand
:bytes) which I found in the RLET macro definition because I missed it
in the documentation and figured that RLET needed to know the size of a
struct to stack allocate it with CCL::%STACK-BLOCK. CCL::MAKE-RECORD
also needs to know the size of a struct to malloc space for one.
If I make it through Learning Carbon, I should have some example code
that is chock full of FFI. The bulk of it in fact. I suspect there
will be some reasonable coverage of the OpenMCL FFI.
More information about the Openmcl-devel
mailing list