tags:

views:

317

answers:

2

I need to create an Objective-C method that converts an int into a byte array. In this instance, I can't use NSArray as a return type, it must be an UInt8 array. I've written a simple method to do this, but it has errors during compile and tells me that I have incompatible return types. Here is the code snippet. Any ideas?

 - (UInt8[])ConvertToBytes:(int) i 
{

     UInt8 *retVal[4];

     retVal[0] = i >> 24;
     retVal[1] = i >> 16;
     retVal[2] = i >> 8;
     retVal[3] = i >> 0;

     return retVal;
}
+2  A: 

You can't return a local C array. You need to malloc(sizeof(UInt8) * 4), populate that, return the pointer and of course don't forget to free it when you're done.

Here's an example of how it would be written and used (just to emphasize the importance of freeing the memory you allocate):

+ (UInt8 *)convertToBytes:(int)i {
    UInt8 *retVal = malloc(sizeof(UInt8) * 4);
    retVal[0] = i >> 24;
    retVal[1] = i >> 16;
    retVal[2] = i >> 8;
    retVal[3] = i >> 0;
    return retVal;
}

- (void)someMethodUsingTheOtherOne {
    int something = 900;
    UInt8 *bytesOfInt = [[self class] convertToBytes:something];
    someFunctionUsingTheBytes(bytesOFInt);
    free(bytesOfInt);
}

(You'll probably notice that I also changed it to be a class method. Since it doesn't depend on any attributes of the instance, it makes more sense for it to be a class method or even just a function. But that doesn't have anything to do with how arrays and pointers work — I just like to use good coding style in examples.)

Chuck
I feel stupid for asking, but can you post the whole solution. I'm new to Objective-C, coming from a Java background, and am still learning the structure of methods, etc.
Adam
@Adam: I updated with an example. By the way, `UInt8`s and C arrays and all that stuff comes from C rather than being specific to Objective-C.
Chuck
This works! Thanks so much for your help. I now see what you were describing. It makes sense.
Adam
+6  A: 

Return the value in a struct. You cannot return C-style arrays from C functions, and this also means that you cannot return them from Objective-C methods either. You can return a struct though, and structs are allowed arrays as members.


// in a header
typedef struct
{
    UInt8 val[4];
} FourBytes;


// in source
- (FourBytes) convertToBytes:(int) i
{
     FourBytes result = { i >> 24, i >> 16, i >> 8, i };
     return result;
}



- (void) someMethod
{
    FourBytes test = [someObject convertToBytes:0x12345678];
    NSLog ("%d, %d, %d, %d", test.val[0], test.val[1], test.val[2], test.val[3]);
}

dreamlax
This is really the better option if you can. Structs are civilized data structures; C arrays will drive you batty.
Chuck
I think it's important to point out that the two are *not* equivalent, though. A struct is not guaranteed to have the same layout as an array. So if you have a function that requires an array of UInt8, passing in a pointer to a struct with four UInt8 members is undefined behavior AFAIK.
Chuck
dreamlax
Yes, certainly. Should have commented a little more carefully, sorry. I just know people get very confused about this, and since this is a very noob-level question, I thought it was important to point out that a struct isn't equivalent to its members.
Chuck