NSArray to C array

cocoa, opengl

Solution

The answer depends on the nature of the C-array.

If you need to populate an array of primitive values and of known length, you could do something like this:

NSArray* nsArray = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],
                                             [NSNumber numberWithInt:2],
                                             nil];
int cArray[2];

// Fill C-array with ints
int count = [nsArray count];

for (int i = 0; i < count; ++i) {
    cArray[i] = [[nsArray objectAtIndex:i] intValue];
}

// Do stuff with the C-array
NSLog(@"%d %d", cArray[0], cArray[1]);

Here's an example where we want to create a new C-array from an `NSArray`, keeping the array items as Obj-C objects:

NSArray* nsArray = [NSArray arrayWithObjects:@"First", @"Second", nil];

// Make a C-array
int count = [nsArray count];
NSString** cArray = malloc(sizeof(NSString*) * count);

for (int i = 0; i < count; ++i) {
    cArray[i] = [nsArray objectAtIndex:i];
    [cArray[i] retain];    // C-arrays don't automatically retain contents
}

// Do stuff with the C-array
for (int i = 0; i < count; ++i) {
    NSLog(cArray[i]);
}

// Free the C-array's memory
for (int i = 0; i < count; ++i) {
    [cArray[i] release];
}
free(cArray);

Or, you might want to `nil`-terminate the array instead of passing its length around:

// Make a nil-terminated C-array
int count = [nsArray count];
NSString** cArray = malloc(sizeof(NSString*) * (count + 1));

for (int i = 0; i < count; ++i) {
    cArray[i] = [nsArray objectAtIndex:i];
    [cArray[i] retain];    // C-arrays don't automatically retain contents
}

cArray[count] = nil;

// Do stuff with the C-array
for (NSString** item = cArray; *item; ++item) {
    NSLog(*item);
}

// Free the C-array's memory
for (NSString** item = cArray; *item; ++item) {
    [*item release];
}
free(cArray);

Problem

Can we convert an NSArray to a C array? If not what alternatives, are there? Suppose I need to feed the C array to OpenGL functions where the C array contains vertex pointers read from plist files.

Original source