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

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.


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

https://github.com/naleksiev/mtlpp


No. Metal is exposed only as an Objective-C API. At best, you could wrap it with a set of Objective-C++ classes, but that would only add overhead, instead of bypassing Objective-C as you desire.


If you want to use Objective-C APIs, but work primarily in C++, your best bet is Objective-C++. This is just Objective-C, but using C++ instead of C as the underlying language.

To convert an Objective-C class to Objective-C++, just change the suffix of the source file from ".m" to ".mm". (You'll also need to make sure to include the proper C++ runtime library at link time.)

Once you've do this, you can use C++ code inside your Objective-C methods, including template types like std::vector as well as C++11 constructs like range-based for loops.