[Openmcl-devel] CGRectMake

Gary Byers gb at clozure.com
Mon Dec 8 00:56:41 UTC 2003

On Mon, 8 Dec 2003, Camille Troillard wrote:

> Hello!
> I have noticed a behavior that I can not understand using a call to the
> FFI function CGRectMake.  If I do for instance:
> ? (#_CGRectMake 0 1 2 3)
>  > Error in process listener(2): Foreign function not found:
> OS::|CGRectMake|
>  > While executing: CCL::LOAD-EXTERNAL-FUNCTION

In order to use any of the interfaces that're in subdirectories of
ccl:darwin-heades; you need to do:

? (use-interface-dir :subdir)

The idea of trying to segregate things like this - making it necessary
to explicitly "use" a set of interefaces - was and is to minimize the
possibility of name conflicts.

OpenMCL does the equivalent of:

(use-interface-dir :libc)

everytime it starts up, so the standard C library things are accessible.

> Then:
> 1 > :pop
> ? (require "COCOA")

The Cocoa example does (use-interface-dir :cocoa), which makes the Cocoa
stuff (and the stuff it depends on, including CoreGraphic, ...) available.

> ? (#_CGRectMake 0 1 2 3)
>  > Error in process Listener(4): Missing arguments in (OS::|CGRectMake|
> 0 1 2 3)
>  > While executing: CCL::%EXTERNAL-CALL-EXPANDER

The first error was caused by the fact that interface files that defined
#_CGRectMake were being used.  This error's caused by the fact that
the call to #_CGRectMake doesn't have enough arguments.  (The arguments
that're there are incidentally not of the right type, but we'll get to
that in a minute.)

A C function that "returns a rectange" (or, more generally, a function
that "returns a structure" that's too big to fit in a machine register)
has to be called specially: the caller has to provide a pointer to a
structure (perhaps one that it's allocated) and pass it as first paramter
to to structure-returning function.  The C function prototype:

CGRect CGMakeRect(float x, float y, float width, float height);

isn't really describing a "function that returns a CGRect", it's
actually describing something more like:

void CGMakeRect(CGRect *hidden_pointer, float x, float y, float width,
                float height);

OpenMCL's interface translator makes this explicit, so the error above
is complaining because it believes that #_CGMakeRect takes 5 arguments
and only 4 were provided.

A C function fragment that used CGMakerect might look like:

  CGRect r;
  r = CGMakeRect(0.0, 1.0, 2.0, 3.0);


In OpenMCL, that'd be:

(rlet ((r :<CGR>ect))
  (#_CGMakeRect r 0.0e0 1.0e0 2.0e0 3.0e0)

Note that in neither case is CGMakeRect "making a rectangle"; in the
C code, it sort of looks that way, but it's really just initializing
or assigning to a rectangle that's already been allocated.

> However CGRectMake is correctly referenced in darwin-headers database
> in the carbon directory.  I really can't explain what's going on
> because I have no problem when calling #_CGContextSetGrayFillColor,
> though I don't have a visual proof it works as I am stuck in writing my
> program, really!
> Thanks in advance for any help,
> Camille

Hope this makes sense.

More information about the Openmcl-devel mailing list