On Nov 22, 2007, at 1:35 PM, Duncan McGregor wrote:
I think that I'm a little out of my depth here. Actually I'm a lot out
of my depth.
I'm trying to call id objc_msgSend_stret(id self, SEL op, ...); from
the OS-X runtime.
The header file has this cryptic little note
* For historical reasons, the prototypes for the struct-returning
* messengers are unusual. The portable, correct way to call these
functions
* is to cast them to your desired return type first.
*
* For example, `NSRect result = [myNSView frame]` could be written
as:
* NSRect (*msgSend_stret_fn)(id, SEL, ...) = (NSRect(*)(id, SEL,
...))objc_msgSend_stret;
* NSRect result = (*msgSend_stret_fn)(myNSView, @selector(frame));
* or, without the function pointer:
* NSRect result = (*(NSRect(*)(id, SEL,
...))objc_msgSend_stret)(myNSView, @selector(frame));
*
* BE WARNED that these prototypes have changed in the past and
will change
* in the future. Code that uses a cast like the example above will be
* unaffected.
The return value part of the cast ensures that the compiler properly
handles the value returned. Defining your JNA method interface is
equivalent to doing the cast; all type information is passed to the
libffi layer, which handles stack setup and capture of the return
value. Currently all returned structures are assumed to be as
pointers by JNA; you might write up some simple tests with a custom
shared lib to see if small structs are handled properly as an
argument and/or return value. libffi for powerpc looks like it
handles small structs, as does x86; JNA may need to be tweaked a bit
to pass structure size information down to libffi, though.