PDA

View Full Version : void *buffers, NSInvocation, and compiler encodings




GeeYouEye
May 15, 2006, 08:39 PM
I'm working on a framework that uses NSInvocation, and I don't know what the return value is going to be from the invocation, or even what size it is ahead of time(could be anything, not just an object). To this end, I'm using -methodReturnSize and -methodReturnType to get the compiler encoding, and parsing that (and boy is that a PITA with structs and unions). No problem, I figure.

So I'm trying to follow the documentation:

First, find the size of the return value.
Second, parse the compiler encoding to make sure the result is going to be the right type. (this is relevant for other parts of the framework, especially since the return value won't always be an object). If it's an object or Class, pass the address of an id I've created for the return value to -getReturnValue:, and return it ([invocation getReturnValue:&retobj]; return retobj;). Otherwise, continue.
Third, to actually get the return value, by creating a void *buffer of the size found in the first step, and passing it to -getReturnValue: (as per the documentation)
Here's the problem: I can't seem to get the value OUT of the buffer. I dereference it (say with [NSNumber numberWithFloat:*buffer]; ) and I get an error or warning about dereferencing a void *. I don't dereference it ([NSNumber numberWithFloat:buffer]) and I get an error for the non-integral types: "Incompatible type..." and a warning for the integral types: "conversion from pointer to integer without a cast".
Last (and once the above is working), wrap the return value in the appropriate object (either one from my framework, NSString, NSNumber, or NSData) and return that.

What am I doing wrong with regards to the buffer?



HiRez
May 15, 2006, 11:10 PM
Here's the problem: I can't seem to get the value OUT of the buffer. I dereference it (say with [NSNumber numberWithFloat:*buffer]; ) and I get an error or warning about dereferencing a void *. I don't dereference it ([NSNumber numberWithFloat:buffer]) and I get an error for the non-integral types: "Incompatible type..." and a warning for the integral types: "conversion from pointer to integer without a cast".
Last (and once the above is working), wrap the return value in the appropriate object (either one from my framework, NSString, NSNumber, or NSData) and return that.

What am I doing wrong with regards to the buffer?Have you tried casting the dereference?

NSNumber myNum = [NSNumber numberWithFloat:(float)*buffer];

or making a new pointer of the target type to the buffer first?

float *floatBuf = (float*)buffer;
NSNumber myNum = [NSNumber numberWithFloat:*floatBuf];

Not sure if those would work, but worth a shot...

EDIT: fixed an error in my code.

GeeYouEye
May 16, 2006, 02:14 AM
The first way doesn't work... the second may take a bit of time to do, as I've got to change the line for each possible compiler encoding (about 2 dozen).

I am, however, inspired to try something along the lines of *(float *)buffer

GeeYouEye
May 16, 2006, 02:34 AM
that worked... now I've just got to parse the compiler encoding for structs, arrays, and unions. not looking forward to that, considering each can contain the others.