[Openmcl-devel] Accessing foreign #define'd constants

David Steuber david at david-steuber.com
Thu Dec 23 02:47:24 UTC 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 

> 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