Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any possibility of using C++ directly with Metal API

Tags:

c++

ios

swift

metal

As Metal Language is also based on C++11, and C++ would seem to be a perfect fit which is a proven performance language, i am looking to altogether bypass Objective-C / Swift. I would love to remain in C++ arena. Is there a possibility?

like image 665
Bilal Ahsan Avatar asked Jan 16 '15 16:01

Bilal Ahsan


2 Answers

Technically yes, but it'd be extremely ugly and might break some other Objective-C parts.

Objective-C, like C++, started life as a preprocessor. One of the legacies of that is that every Objective-C method is also exposed as a C function call that takes the object instance and the method selector as the first two arguments respectively, then the other declared arguments in left-to-right order.

Both NSObject and the C calls that form the Objective-C runtime can look up the current C function that would be called for any method call.

You could therefore create a C++ class that grabbed all the C function pointers (it could even do this from the C runtime, making it pure C++ code and not Objective-C++) and jumped straight to the appropriate code like that.

The downsides are: Objective-C normally uses dynamic dispatch (i.e. method resolved to C function on each call) and mechanisms like key-value observing work only because it uses dynamic dispatch. If you grab the C function pointer before someone else starts observing then your calls are going to make to update the property without notifying observers. So you're potentially going to break some modules.

That warning being issued, and assuming you can just build your C++ bridge class as Objective-C++ for simpler syntax e.g.

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));
}

... where I've conveniently declined to cast the result of +instanceMethodForSelector: to the appropriate type because I'm confident I'll get it wrong. I tend to chicken out and introduce an intermediate typedef in my actual code but you may prefer to be more terse.

like image 80
Tommy Avatar answered Sep 29 '22 12:09

Tommy


The following Open Source project provides a C++ wrapper for Metal:

https://github.com/naleksiev/mtlpp

like image 30
Mortennobel Avatar answered Sep 29 '22 13:09

Mortennobel