Leem.fin Leem.fin - 3 months ago 21
Objective-C Question

Use NSValue to wrap a C pointer

I have a C type pointer variable:

a_c_type *cTypePointer = [self getCTypeValue];


How can I convert
cTypePointer
to
NSObject
type & vise versa?

Should I use
NSValue
? What is the proper way to do so with
NSValue
?

Answer

You can indeed use a NSValue.

a_c_type *cTypePointer = [self getCTypeValue];
NSValue * storableunit = [NSValue valueWithBytes:cTypePointer objCType:@encode(a_c_type)];

note that the 1st parameter is a pointer (void*). the object will contain the pointed value.

to get back to C:

a_c_type element;
[value getValue:&element];

Note that you would get the actual value, not the pointer. But then, you can just

 a_c_type *cTypePointer = &element

Test it :

- (void) testCVal
{
    double save = 5.2;
    NSValue * storageObjC = [NSValue valueWithBytes:&save objCType:@encode(double)];


    double restore;
    [storageObjC getValue:&restore];

    XCTAssert(restore == save, @"restore should be equal to the saved value");

}

test with ptr :

typedef struct
{
    NSInteger day;
    NSInteger month;
    NSInteger year;
} CDate;

- (void) testCVal
{
    CDate save = (CDate){8, 10, 2016};
    CDate* savePtr = &save;

    NSValue * storageObjC = [NSValue valueWithBytes:savePtr objCType:@encode(CDate)];


    CDate restore;
    [storageObjC getValue:&restore];
    CDate* restorePtr = &restore;

    XCTAssert(restorePtr->day == savePtr->day && restorePtr->month == savePtr->month && restorePtr->year == savePtr->year, @"restore should be equal to the saved value");

}