gpt4 book ai didi

objective-c - 将 ObjC id 和类型对象转换为 C 指针 (void *) 然后将其转换回去是否安全?

转载 作者:太空宇宙 更新时间:2023-11-04 07:54:35 24 4
gpt4 key购买 nike

我正在为 Metal API ( http://github.com/recp/cmtl) 开发 C 包装器/绑定(bind)。

我在 C header 中将 Objective-C 类型定义为 void,例如 typedef void MtDevice .然后我将在 ObjC 函数中分配的对象转换为 void* 指针。然后将其转换回 ObjC 以调用 ObjC 函数。

这里是我的代码[s]:

ARC 样式:

MtDevice*
mtDeviceCreat() {
id<MTLDevice> mdevice;
mdevice = MTLCreateSystemDefaultDevice();
return (void *)CFBridgingRetain(mdevice);
}

MtCommandQueue*
mtCommandQueue(MtDevice *device) {
id<MTLDevice> mdevice;
id<MTLCommandQueue> mcmdQueue;

mdevice = (__bridge id<MTLDevice>)device;
mcmdQueue = [mdevice newCommandQueue];

return (void *)CFBridgingRetain(mcmdQueue);
}

ARC 禁用:

MtDevice*
mtDeviceCreat() {
id<MTLDevice> mdevice;
mdevice = MTLCreateSystemDefaultDevice();
return [mdevice retain];
}

MtCommandQueue*
mtCommandQueue(MtDevice *device) {
id<MTLDevice> mdevice;
id<MTLCommandQueue> mcmdQueue;

mdevice = (__strong id<MTLDevice>)device;
mcmdQueue = [mdevice newCommandQueue];

return [mcmdQueue retain];
}

我正在考虑禁用 ARC,因此我将其转换为第二个版本。这里有几个问题:

  1. newCommandQueue 之后和类似的功能我应该在返回之前保留对象吗?
  2. 我用了mdevice = (__strong id<MTLDevice>)device;将 void* 转换为 ObjC 类型,但是这个呢:mdevice = device; ?编译器似乎没有提示。
  3. 对于 ARC 和非 ARC,像我一样在 ObjC 类型和 C void* 之间进行转换是安全的吗?

PS:我的 C 函数只是从 C 调用 ObjC 函数的包装器。我并没有尝试访问 C 函数中的 ObjC 类成员。

编辑:

发布代码:

void
mtRelease(void *obj) {
[(id)obj release];
}

编辑 2:

更新代码(禁用 ARC):

MtDevice*
mtDeviceCreat() {
return MTLCreateSystemDefaultDevice();
}

MtCommandQueue*
mtCommandQueue(MtDevice *device) {
return [(id<MTLDevice>)device newCommandQueue];
}

最佳答案

在这两种情况下,对 -retain 的调用是不正确的。 MTLCreateSystemDefaultDevice() 遵循 the Create Rule , 所以它已经为你保留了。您负责一次(自动)发布以平衡原始创作,并为您执行的每个 -retain 负责一次。

同样,-newCommandQueue 返回一个已保留且您最终必须释放的对象。 That's true of any method starting with "new" .

__strong 在禁用 ARC 时不执行任何操作。 mdevice = device; 没问题。

将 Objective-C 对象指针转换为 void* 并返回是“安全的”(除了类型安全的损失)。我建议您使用指向不透明结构类型的指针而不是 void*,以保持类型安全。例如,typedef struct MtDevice *MtDeviceRef;,其中从未定义 struct MtDevice。这就是 Apple 定义自己的类型的方式,例如 CFStringRef

关于objective-c - 将 ObjC id<Protocol> 和类型对象转换为 C 指针 (void *) 然后将其转换回去是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51078135/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com