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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With