【问题标题】:Use NSValue to wrap a C pointer使用 NSValue 包装一个 C 指针
【发布时间】:2016-08-11 07:39:37
【问题描述】:

我有一个 C 类型的指针变量:

a_c_type *cTypePointer = [self getCTypeValue];

如何将cTypePointer 转换为NSObject 类型,反之亦然?

我应该使用NSValue 吗?使用NSValue 的正确方法是什么?

【问题讨论】:

  • 你想用指针做什么?您不能只是将某些东西转换为 NSObject 引用。
  • @Avi,为什么不能?我发现 NSValue 是我需要的东西,但不知道在我的情况下使用它的正确方法,所以我在这里问。
  • 因为您使用了错误的术语。 NSValue 存储一个值。它不会从一种类型转换为另一种类型。
  • NSValue 确实存储了一个值,它可以是任何 C 类型,只要它知道信息的第 1 位的地址和要读取的长度即可。指针和类型。所有 NSValue 都需要。当然,术语“wrap”会比“convert”更好,但是,仍然
  • 我以后会尽量使用更准确的术语,但我想人们会理解我想问的问题。

标签: ios objective-c nsobject nsvalue


【解决方案1】:

你确实可以使用 NSValue。

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

注意第一个参数是一个指针(void*)。该对象将包含指向的值。

回到C:

a_c_type element;
[value getValue:&element];

请注意,您将获得实际值,而不是指针。但是,你可以

 a_c_type *cTypePointer = &element

测试一下:

- (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");

}

用 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");

}

【讨论】:

  • 谢谢,我会尽快尝试并回复您。
  • 嗯......它对我不起作用......你能不能对原始类型'double'的c类型指针进行测试?
  • 我明白了,以@Florian Burel 的回答作为参考,我需要'restore' 变量,然后将其地址分配给restorePtr,我错过了这一步。现在它也适用于我!
【解决方案2】:

您只需使用方法valueWithPointer: 将指针值包装为NSValue 对象,并使用pointerValue 方法提取指针值。

这些就像valueWithInt:/intValue et al - 它们包装原始值。您没有包装指针指向的内容。因此,重要的是要确保在提取指针时它所指向的指针仍然存在,否则指针值将无效。

最后,您必须将作为void * 返回的提取指针值转换回其原始类型,例如a_c_type * 在您的示例中。

(如果您想包装指向的内容,请考虑NSData。)

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多