== Objective-C and Objective-C++ == On the mailing list, a general description of Objective-C and Objective-C++ was given (following the submission of osgsimpleviewerCocoa). This archive seems to have been lost, but the explanation has proven useful for those not familiar with the language. The original post has been recovered and placed here for reference. Additional information, follow-up posts, etc. are welcome on this page. ---- {{{ > Hi Eric, > > I know little about Objective-C++/C or Cocoa, so please excuse a few > dumb questions from C++ land. I understand that Obj-C and especially Obj-C++ fall outside of most people's knowledge base. I only recently picked it up myself. I'm still learning as I go (and as I try to pick up more of Lua as well). So here's some background info to setup some context: Objective-C was created in the early 1980's. It is not a new language by far. It is heavily influenced by Smalltalk. Objective-C can be described as the closest thing you can get to Smalltalk in a C-based language. Objective-C is a dynamic language (dynamic typing, dynamic binding, dynamic loading). And Objective-C has strong support for introspection and reflection. In many respects, it is more comparable to languages like Python or Ruby than to C++. The presence of these features is felt in the fact that tools like Interface Builder or universal generic undo support can exist. It also makes language bridges relatively easy to create. On OS X, writing complete Cocoa apps in Python is very viable. There is also a Ruby bridge which looks like it is coming into maturity. I personally use a small bridge for some things called the LuaObjCBridge. It is by no means as complete or mature as the PyObjC bridge, but at the time, the entire binding was under 1500 lines of code which I find impressively small. Objective-C is a single inheritance language. Objective-C supports Protocols (Java later called their feature Interfaces). Objective-C supports Delegates (C# has them now) Objective-C supports Categories, which allow you to add or override methods in a class without subclassing it. Because of Objective-C's dynamic typing, you don't have/need templates. Objects in Objective-C must be created on the heap. So you always use pointers to refer to objects. Objective-C currently uses manual or semimanual reference counting for objects (somewhat similar to osg::ref_ptr). OS X 10.5 Leopard is introducing Objective-C 2.0 which includes automatic garbage collection. Objective-C is less susceptible to the fragile base class and fragile binary class problems than C++. I heard this is partly why Apple bought NeXT instead of BeOS (which was C++ based). (Java solved this problem and this is another reason Microsoft needed to pick a new language away from C++.) Objective-C is a 100% superset of C. So anything that is valid C is also valid Obj-C. (Contrast to C++, which is not a 100% superset of C which has implications when combining C and C++ code.) Objective-C is a relatively simple language with minimal extensions to C. If you already know C or C++, you can learn most of Obj-C in a day. Objective-C syntax is orthogonal to C and C++. Some complain about the weird syntax, but this is also prevents clashes which allows Objective-C++ to work. Typically new keywords are prefixed with @. And the messaging syntax differs from a C++ method call. Probably the hardest thing for C/C++ programmers to get over is the messaging syntax. Keeping in mind that message passing has some subtle implications over a function call, but ignoring that, the translation is as follows: // C++ style method call (example stolen from Wikipedia) window.addNewControl("Title", 20, 50, 100, 50, true); // Obj-C message [window addNewControlWithTitle:@"Title" xPosition:20 yPosition:50 width:100 height:50 drawingNow:YES]; Brackets denote the message. We send the message to the object 'window'. Objective-C uses named parameters like the above (though parameter order matters which some would argue are not 'true' named parameters). It's more verbose, but it's self documenting. (FYI, the @ symbol in front of the string "Title" tells the compiler that it is a string that has all the Unicode goodness so it internationalizes more easily than char*. It's one of those additional syntax things to avoid C/C++ clashing.) So Objective-C clearly lost the language war against C++ in the 80s and 90s. However, there has been sort of a renaissance of late. People have finally figured out that C++ isn't the best solution for all problems. Dynamic languages like Perl, Python, Ruby, Lua, etc. have come onto the scene demonstrating that C++'s type rigidness and minimal introspection and reflection support are liabilities more than assets for certain types of tasks. GUI programming is one of these tasks. This is one of the reasons that Microsoft picked a new language to base their stuff on (C#). They realized that they needed a language that was more dynamic than C/C++. This is where Objective-C excels, which is what NeXT realized way back over a decade ago. Objective-C was the foundation for their GUI API because it offered both a clean objected-oriented way to do things, but also because of the language's dynamism. If somebody were to pick a new base language today to be the basis of a new GUI framework, (not counting Microsoft), I suspect a language like Python or Ruby would be the basis. So what is Objective-C++? Objective-C++ is a language extension that lets you put both Objective-C and C++ code in the same file and interact. Before Objective-C++, you would be forced to wrap stuff from both so they communicate through their common denominator, C (well, almost common denominator in C++'s case). Objective-C++ exists for convenience to save the programmer time from having to do this extra work. The philosophy behind Objective-C++ is "peaceful coexistence". The designers wisely decided to avoid creating a monster of a language. So they took the approach that you can mix the two languages, and you can contain objects within the other language, but you can't subclass between the two languages. So I can't take a C++ class, and make it inherit from an Objective-C class or vice-versa. The obvious benefit of this is that no new rules need to be invented and both C++ and Obj-C objects behave identically as described in their fundamental languages. To convert objects, Objective-C++ does nothing here either. (This somewhat follows the C++ minimalist philosophy.) The benefit of course is that nothing strange has to happen. So if you do need to convert objects, you do that manually. Since both languages can speak to C (and primitive data types), this is the most obvious communication layer. So for example, if you need to convert an std::string to an NSString,, you get the char* representation from the std::string using .c_str(), and then feed it to NSString. So when you ask, how is this going to behave in Objective-C++, once you factor in the "peaceful coexistence" philosophy, the answer is pretty much, 'as you would expect'. // Mixing Example: // This example is a little bad because I really need to reference count NSColor. // I should be using something like osg::ref_ptr but for Obj-C objects or should be // explicitly retaining the objects. std::vector vector_of_colors; list_of_colors.push_back([NSColor blueColor]); list_of_colors.push_back([NSColor redColor]); list_of_colors.push_back([NSColor greenColor]); // Cpp class definition example with Obj-C stuff class CppExample { public: void setColor(NSColor* the_color); private: NSColor* someColor; std::vector listOfColors; }; // Obj-C class definition example with C++ stuff @interface ObjCExample : NSObject { // instance variables go inside the braces osg::Vec4 someColor; std::vector listOfColors; } // methods go outside the braces, but before @end - (void) setColor:(const osg::Vec4&)the_color; @end So finally to your questions: * How do you integrate the Objective-C++ code into a C++ application? So any file that has both C++ and Objective-C, you compile as Objective-C++. (This is most easily accomplished by naming the file extension as .mm.) If the file is just C++, then just compile as C++. Conversely, if the file is Objective-C, just compile as Obj-C (.m). The linker seems to just do the correct thing with all the object files when you put them together. * How do objects created in Objective-C++ look/behave on the C++ side? Exactly like C++ * How do C++ look/behave on the Objective-C++? Exactly like C++ * When writing a cross platform app what do you do about managing code between OSX specific pathways and more conventional C++ style widget API? * I am generally curious, and also interested from the perspective of writing osgViewer, i.e. how do I keep the core code general purpose enough to work cross platform easily, whilest still providing another hooks/mechnansim to allow good native support. Cocoa is quite unusual when compared to the likes of Qt/WxWindows/Fox/MFX/X11 ;-) So 'conventional C++' is a little loaded. I think NeXTSTEP predates most of those libraries except for X11 which is C-based, right? And certainly remember that Obj-C works better with C than C++ does being that Obj-C is a pure superset. And wxWidgets looks like it copied MFC as its design template. But I know what you're getting at. Honestly, this isn't an area I have much experience in. I usually come from the other direction or use a toolkit that already implemented this. The problem I found with the cross-platform kits out there is that at best they are Windows centric. This usually results in a very poor user experience on the Mac. Often they stick out like a sore thumb and don't support functionality that Mac users consider basic/fundamental (drag-and-drop, copy/paste, proper keyboard shortcuts, services, etc). So my approach has been what we've done with the simpleviewers like osgsimpleviewerGLUT/SDL/Cocoa. In my stuff, all the core/cross-platform functionality is at the lowest level, and then I build platform specific layers on top. But I will try to suggest some ideas here. Specifically with C++, I would try to isolate the C++ and Obj-C code as much as possible. You can do this pretty much the same way you would shelter C and C++ from each other. In the C/C++ case, basically in header files that need to be included by both, make sure the header is C clean. What you do in the implementation files is open season. Void pointers and forward declarations can help keep headers clean. For Obj-C/C++, you probably want to try to make headers C++ clean (or C clean). Forward declarations and/or void pointers can help here too in C++ class definitions that need to hold members to Obj-C members. I document this a little bit in my header file for simpleviewerCocoa. So the multiple inheritance technique in the Qt viewer example worries me because I don't think that's going to fly with Objective-C or any non C++ language. In the Objective-C/Cocoa case, the NSView Objective-C class instance will receive the events. You can't subclass a C++ class from a Obj-C class. So the only policy is some kind of containment. Maybe another example to consider is how one would implement the viewer for GTK+ through the C API. How would one approach GTK integration in this case? And then I also wonder about people using language bindings such as Java, C#, Python, Ruby, etc. These languages don't support multiple inheritance. Anyway, if we can come up with a good design that gets around the inheritance requirement, may there is a chance that it will solve the problem with Cocoa/Obj-C. Or maybe GLUT is the model to look at? It is already cross platform and provides native back ends for different platforms. It uses Cocoa on Mac. Source code is open. I hope this is helpful. -Eric }}} === Additional References === See [http://www.openscenegraph.org/projects/osg/wiki/Support/Tutorials/MacOSXTips "Mac OS X Tips and Tricks"] for more information/videos on getting started with Mac OS X and Xcode.