0

I have an NSArray* containing my own objects that I need to access from a C api. Hitting my objects from C functions is working fine, but when I try to copy them to a C array, I can see the pointers being cleared after some time!

@interface MNCircularBufferPlayer;// just assume this exists

void schedule(MNPlayList* playlist){ /* some C code */}

typedef struct MNPlayList { 
    __unsafe_unretained MNCircularBufferPlayer **players;
    int playersCount;
} MNPlayList;

-(void)sendToCApi(){
//...    
    NSArray* toCopy = self.players; // array of MNCircularBufferPlayer instances
    MNPlayList* playlist=malloc(sizeof(MNPlaylist));
    playlist->playersCount=toCopy.count;
    playlist->players=(__unsafe_unretainedNCircularBufferPlayer**)calloc(toCopy.count+1,sizeof(MNCircularBufferPlayer*));
    for(MNCircularBufferPlayer* player in toCopy){
      playlist->players[i]=player;
    }
    //.. send to C api
} 

When inspecting the memory after this point, the buffer contained within my struct looks OK. But when the C function gets the same struct, the struct has the same size, but the contents of the buffer are all 0x30000000! I am entirely positive the MNCircularBufferPlayer instances are still retained! There's even a breakpoint in dealloc just to be 100% sure...

I gave-up and ended using a linked-list instead, and it works:

typedef struct MNPlayList {
    __unsafe_unretained MNCircularBufferPlayer *player;
    struct MNPlayList *next;
} MNPlayList;

But I am losing sleep over this one.

0

1 Answer 1

1

As the objects in the NSArray must be Objective-C objects, it's not clear how you expect to actually use those objects from C, but anyway...

This creates an array of MNCircularBufferPlayer * objects with nil as the last element as a sentinel:

-(void)sendToCApi(){
    MNCircularBufferPlayer *carray = malloc(sizeof(MNCircularBufferPlayer *) * ([self.players count] + 1]));
    for (NSUInteger i = 0; i < [self.players count]; i++)
        carray[i] = self.players[i];
    carray[[self.players count]] = nil;

    //.. send to C api

    free(carray);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.