Я работаю над оболочками / привязками C для Metal API (http://github.com/recp/cmtl).
Я определил типы Objective-C как пустые в заголовках языка Си, например typedef void MtDevice
. Затем я приведу объект, выделенный в функции ObjC, к указателю void *. Затем приведем его обратно к ObjC для вызова функции ObjC.
Вот мой код [с]:
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, поэтому я преобразовал его во вторую версию. Несколько вопросов здесь:
- После
newCommandQueue
и аналогичных функций следует ли сохранять объект перед его возвратом?
- Я использовал
mdevice = (__strong id<MTLDevice>)device;
, чтобы привести void * к типу ObjC, но как насчет этого: mdevice = device;
? Вроде компилятор не жалуется.
- Как в ARC, так и в не ARC безопасно выполнять приведение между типами ObjC и C void *, как я сделал?
PS: Мои функции C являются только оболочками для вызова функций ObjC из C. Я не пытаюсь получить доступ к членам класса ObjC в функциях C.
EDIT:
Код выпуска:
void
mtRelease(void *obj) {
[(id)obj release];
}
РЕДАКТИРОВАТЬ 2:
Обновленный код (ARC отключен):
MtDevice*
mtDeviceCreat() {
return MTLCreateSystemDefaultDevice();
}
MtCommandQueue*
mtCommandQueue(MtDevice *device) {
return [(id<MTLDevice>)device newCommandQueue];
}