I am using a third-party library that requires a C callback in an iOS program. The callback provides a void*
userdata parameter that I can use as I wish. In this callback I want to create an NSData object that is returned to the code that invokes the API that eventually calls the callback. For example:
// C callback:
static void callback(int x, void* userdata)
{
if (userdata)
{
// This gives an error:
// Pointer to non-const type 'NSData*' with no explicit ownership
NSData** p = (NSData**)userdata;
*p = [NSData init:...];
}
}
// main code:
NSData* d = ...; // sometimes valid, sometimes nil
library_api(callback, &d); // have the callback initialize or replace d
if (d)
{
[d doSomthing:...];
}
I am using ARC, which I think is at the root of the issues. I thought of using a struct to hold the NSData*
, but ARC forbids Objective-C objects in structs or unions. There is probably some variant of __bridge
that might help, but I am not sure which. I have looked at a lot of SO questions and read the Apple docs, but it is not clear to me how to code this up.
Ideally, if d were not nil at the time the callback is invoked, its current value would be released and a new NSData object would replace it. In other words, when library_api completes, d always holds the NSData object created by the callback, and any previously held value would have been released properly.
I suppose I could keep the Objective-C code out of the callback and just malloc()
a buffer to store the data which would then be copied to an NSData object in the main code, but I am hoping that I can avoid that extra step.