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.
Reading this I think its saying that you should call the fn as if it
didn't take struct*, and does return the struct by value! I can only
think that its written in assembler and messes with the stack, but
variably, depending on the size of the value returned by the message
send.
My problem is that I need to call this to invoke messages which return
arbitrary structs, decided at runtime, and so don't have the luxury of
a sneaky function pointer cast in order to get my stack fixed up
properly after the call. Hence the crash I was seeing earlier.
My impression is that deep in its bowels jna is interpreting the
desired return value for a function in order to decide how many bytes
to pull of the stack - after all it doesn't have a prototype to go on.
So it could use the size of a Structure to do the same? But this is in
the native implementation?. BTW, I am in awe, at least on the Java
side its great stuff.
I'd welcome any pointers ;-) for how I might approach adding return
structure by value, and whether it can be dynamic enough to solve my
problem.
Cheers
Duncan