Up vote 13 down vote favorite 2 share g+ share fb share tw.
So, I was bored today, and decide to mess with C++/Obj-C interpolation, and I found a way to create a very interesting setup. @protocol NSCPPObj -(id) init; -(id) initWithInt:(int) value; -(int) somethingThatReturnsAValue; -(void) doSomething; @end class NSCPPObj : objc_object { public: static Class cls(); int iVar; NSCPPObj(); NSCPPObj(int); int somethingThatReturnsAValue(); void doSomething(); }; As you can see, the interface is quite straightforward, and easy to understand. We create two (almost) identical interfaces, one for a C++ object, and another for a Obj-C protocol.
Now, I found a way to implement this, but brace yourself, this gets ugly: // NSCPPObj. Mm #import #import #import "NSCPPObject. H" Class NSCPPObj_class = nil; __attribute__((constructor)) static void initialize() { NSCPPObj_class = objc_allocateClassPair(NSObject class, "NSCPPObj", 0); class_addMethod(NSCPPObj_class->isa, @selector(alloc), imp_implementationWithBlock(^(id self) { return class_createInstance(NSCPPObj_class, sizeof(struct NSCPPObj)); }), "@@:"); class_addMethod(NSCPPObj_class, @selector(init), imp_implementationWithBlock(^(id self) { return self; }), "@@:"); class_addMethod(NSCPPObj_class, @selector(initWithInt:), imp_implementationWithBlock(^(id self, int value) { ((struct NSCPPObj *) self)->iVar = value; return self; }), "@@:i"); class_addMethod(NSCPPObj_class, @selector(doSomething), imp_implementationWithBlock(^(id self) { ((struct NSCPPObj *) self)->doSomething(); }), "v@:"); class_addMethod(NSCPPObj_class, @selector(somethingThatReturnsAValue), imp_implementationWithBlock(^(id self) { return ((struct NSCPPObj *) self)->somethingThatReturnsAValue(); }), "i@:"); objc_registerClassPair(NSCPPObj_class); } Class NSCPPObj::cls() { return NSCPPObj_class; } NSCPPObj::NSCPPObj() { this->isa = NSCPPObj_class; ((id) this) init; } NSCPPObj::NSCPPObj(int value) { this->isa = NSCPPObj_class; ((id) this) initWithInt:value; } void NSCPPObj::doSomething() { std::cout ) this) somethingThatReturnsAValue obj = NSCPPObj::cls() alloc initWithInt:15; obj doSomething; NSLog(@"%i", obj somethingThatReturnsAValue); NSLog(@"%@", obj); NSCPPObj *objAsCPP = (__bridge NSCPPObj *) obj; objAsCPP->doSomething(); std::cout somethingThatReturnsAValue() Obviously, this can work in a ARC or non-ARC environment, but ARC requires a few extra bridged casts.
So, I come to the real question: What are the pros/cons of this design structure? I can list a few off of the top of my head: Pros: Operator Overloading with C++ Dynamic method binding with ObjC Can be constructed in either a C++ or ObjC fashion Cons: Hard-to-read implementation Selectors & bindings must be added for every C++ implementation added to the interface Class object cannot be referenced directly So, after all that, would you recommend this design structure in an application? And why.
C++ objective-c ios cocoa objective-c++ link|improve this question edited Apr 4 at 18:23bbum66.2k779166 asked Apr 4 at 15:48Richard J. Ross III10.6k12053 98% accept rate.
1 I know too little C++ to give this a good go answering, but I wonder if the answer to this depends on exactly what kind of application you're working on. An existing C++ game being ported over could find this much more useful than a simple utility app...and a seasoned C++ programer may appreciate it more than someone who's heavily Objective-C oriented. – lxt Apr 4 at 15:53 Voting to reopen.
I understand how this may be 'not constructive', but this is a community site. I recognize you are a moderator, but seeing as you are the only one who wanted this to close. – Richard J.
Ross III Apr 4 at 17:04 I'm not a moderator and I flagged this question for review. It is off-topic. – mydogisbox Apr 4 at 17:24 2 This is a constructive, on-topic, question that is helpful to Mac OS X and iOS developers.
This is an issue often faced by developers in that market that are leveraging any of the several hundred (thousands? ) of various C++ engines that are available. Certainly, the example, itself is superfluous to the pros/cons/specific-question at the end, but the actual question of Is generic bridging between ObjC and C++ a recommended pattern and why?
Is very much a concrete question of value! – bbum Apr 4 at 17:49 1 I'd also like to note that the same operator-overloading that you get here could be duplicated with a C++ wrapper around an Objective-C object. Then, provide an implicit conversion to id.
I'm not endorsing that technique, but pointing out that it is probably a simpler solution to that particular problem. – Jonathan Sterling Apr 4 at 18:21.
And why. No. It is a really nice bit of code; I particularly like the use of imp_implementationWithBlock() (but I admit I might be partial to that particular feature of the runtime ;).
And, of course, explorations like this are always an incredibly valuable learning tool. The issue, in the context of "real world paying project" use, is that you are effectively creating a relatively generic bridge that will then have to have specific bridges at either end to interface with either typical C++ libraries or typical Objective-C APIs/libraries. To put it another way, you have effectively created a new runtime derived from an amalgamation of two existing runtimes.
And, as you point out in the Cons, you pretty much have to touch, wrap, modify and/or debug a shim on top of every C++ class you want to bring into this pattern. In working with quite a bit of Objective-C++ code over the last 20+ years, a bridge like this is generally more trouble than it is worth. You would likely be better off -- spend less time writing and debugging code -- creating simple Objective-C wrappers around the C++ (or C, frankly) APIs that can then be integrated with and consumed by the targeted system's Objective-C frameworks.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.