是否有可能直接在Metal API中使用C ++

时间:2015-01-16 16:41:25

标签: c++ ios swift metal

由于Metal Language也基于C ++ 11,而C ++似乎是一种完美的契合,这是一种经过验证的性能语言,我期待完全绕过Objective-C / Swift。我很想留在C ++舞台上。有可能吗?

4 个答案:

答案 0 :(得分:6)

技术上是的,但它非常难看,可能会破坏其他一些Objective-C部件。

Objective-C与C ++一样,起初是一个预处理器。其中一个遗产是每个Objective-C方法也作为C函数调用公开,它将对象实例和方法选择器分别作为前两个参数,然后以从左到右的顺序将其他声明的参数。

构成Objective-C运行时的NSObject和C调用都可以查找为任何方法调用调用的当前 C函数。

因此,您可以创建一个C ++类来抓取所有C函数指针(它甚至可以从C运行时执行此操作,使其成为纯C ++代码而不是Objective-C ++)并直接跳转到相应的代码。 / p>

缺点是:Objective-C通常使用动态调度(即每次调用时解析为C函数的方法)和键值观察等机制仅因为它使用动态调度。如果你在其他人开始观察之前抓住C函数指针,那么你的调用将在没有通知观察者的情况下更新属性。所以你可能会打破一些模块。

发出警告,并假设您可以将您的C ++桥类构建为Objective-C ++,以实现更简单的语法,例如

class MTLArray {
    id m_instance;
    static NSUInteger (* s_arrayLength)(id object, SEL selector);
};

MTLArray::MTLArray() {
    // assuming you use the m_ pattern for instance variables
    m_instance = [MTLArray new];

    // assuming you use s_ for static variables; also pretending
    // the mapping from method to C function will never change —
    // KVO is the most prominent exception but otherwise you can
    // be exceedingly confident, albeit you'll be relying on
    // empirical behaviour, not the formal contract
    if(!s_arrayLength) {
        s_arrayLength = [MTLArray instanceMethodForSelector:@selector(arrayLength)];
    }
}

NSUInteger MTLArray::getArrayLength() {
    return s_arrayLength(m_instance, @selector(arrayLength));
}

...我方便地拒绝将+instanceMethodForSelector:的结果投射到合适的类型,因为我有信心我会弄错。我倾向于在我的实际代码中剔除并引入中间typedef,但您可能更喜欢更简洁。

答案 1 :(得分:1)

如果您想使用Objective-C API,但主要使用C ++,最好的选择是Objective-C ++。这只是Objective-C,但使用C ++而不是C作为底层语言。

要将Objective-C类转换为Objective-C ++,只需更改来自" .m"的源文件的后缀。到" .mm"。 (您还需要确保在链接时包含正确的C ++运行时库。)

完成此操作后,您可以在Objective-C方法中使用C ++代码,包括std :: vector等模板类型以及基于范围的for循环等C ++ 11构造。

答案 2 :(得分:1)

以下开放源代码项目为Metal提供了C ++包装器:

https://github.com/naleksiev/mtlpp

答案 3 :(得分:0)

没有。 Metal仅作为Objective-C API公开。最好的情况是,您可以使用一组Objective-C ++类来包装它,但这只会增加开销,而不是根据需要绕过Objective-C。

相关问题