Another fine day on IRC. An individual was stating that you couldn’t pass C arrays to Objective-C methods. That surprised me, so I wrote a little little command line program to check (the program is at lisppaste.) Of course, it turns out you can – Objective-C is still just C. And because it’s just C, you have the behavior of arrays and pointers being pretty much interchangeable.
For instance, you can pass a C array to a method:
- (void) ookie: (int *) snork {
NSLog (@"%d %d %d", snork[0], snork[1], snork[2]);
} // ookie
Or use the [] syntax:
- (void) ookie2: (int[]) snork;
or use the explicit size syntax (which doesn’t really matter for 1-D arrays):
- (void) ookie3: (int[17]) snork;
And you can pass in pointers to pointers to pass back a resized array originally allocated by malloc:
- (void) ookie4: (int**) snork
growTo: (int) elements {
*snork = realloc(*snork, sizeof(int) * elements);
(*snork)[0] = 55;
NSLog (@"(%d) %d %d %d", sizeof(snork), (*snork)[0], (*snork)[1], (*snork)[2]);
} // ookie4
Passing in arrays of Objective-C types isn’t a problem either:
- (void) ookie: (NSString **) snork {
NSLog (@"%@ %@", snork[0], snork[1]);
} // ookie
Just make sure your syntax is declaring the original array is good:
NSString *blargh[] = { @"oop", @"ack" };
(the original poster had confusion about Objective-C objects needing to be pointers, having a declaration of NSColor blargh[] = { ... }; and then stating that things aren’t possible)
It does go without saying that you should prefer NSArray, or another collection class, to naked C arrays. Sometimes you need to use the lower-level mechanisms, so the power (and pain) is there if needed.




Very helpful. I have to pass an array using a void pointer and will try this. Thanks.
Comment by Daniel — May 16, 2008 @ 10:59 am
Mark,
this works, but it results in the following compilation warning at the calling locations:
warning: passing argument 1 of ‘myFunc’ discards qualifiers from pointer target type
It would be nice to know a way around that…
Tom
Comment by Tom — May 28, 2008 @ 12:38 am
Sounds almost like you’ve got a const/non-const thing going. Can you post the code? (like your ObjC method taking C stuff, and where you’re calling it from. And also if you’re in C or C++ land)
This stuff compiles and runs OK for me: (Let’s see if the html gets mangled by wordpress… Looks like I can use ‘code’ but not ‘pre’)
#import <Foundation/Foundation.h>
/* compile with
gcc -g -Wall -framework Foundation -o justc justc.m
*/
@interface Snorgle : NSObject
- (void) ookie: (int *) snork;
- (void) ookie4: (int**) snork
growTo: (int) elements;
- (void) ookie5: (NSString **) snork;
@end // Snorgle
@implementation Snorgle
- (void) ookie: (int *) snork {
NSLog (@"%d %d %d", snork[0], snork[1], snork[2]);
} // ookie
- (void) ookie4: (int**) snork
growTo: (int) elements {
*snork = realloc(*snork, sizeof(int) * elements);
(*snork)[0] = 55;
NSLog (@"(%d) %d %d %d", sizeof(snork), (*snork)[0], (*snork)[1], (*snork\
)[2]);
} // ookie4
- (void) ookie5: (NSString **) snork {
NSLog (@"%@ %@", snork[0], snork[1]);
} // ookie5
@end // Snorgle
int main (void) {
Snorgle *snorgle = [[Snorgle alloc] init];
int blah[] = {1, 2, 3};
[snorgle ookie: blah];
int *fnork = malloc(sizeof(int) * 4);
fnork[0] = 18; fnork[1] = 20; fnork[2] = 22; fnork[3] = 24;
[snorgle ookie4: &fnork
growTo: 37];
NSString *blarg[] = { @"oop", @"ack" };
[snorgle ookie5:blarg];
return (0);
} // main
Comment by Mark Dalrymple — May 28, 2008 @ 8:42 am