Use C++ with Cocoa Instead of Objective-C

Use C++ with Cocoa Instead of Objective-C?

You cannot write a Cocoa application entirely in C++. Cocoa relies heavily on the late binding capabilities of Objective-C for many of its core technologies such as Key-Value Bindings, delegates (Cocoa style), and the target-action pattern. The late binding requirements make it very difficult to implement the Cocoa API in a compile-time bound, typed language like C++ⁱ. You can, of course, write a pure C++ app that runs on OS X. It just can't use the Cocoa APIs.

So, you have two options if you want to share code between C++ apps on other platforms and your Cocoa-based application. The first is to write the model layer in C++ and the GUI in Cocoa. This is a common approach used by some very large apps, including Mathematica. Your C++ code can be left unchanged (you do not need "funky" apple extensions to write or compile C++ on OS X). Your controller layer will likely make use of Objective-C++ (perhaps the "funky" Apple extension you refer to). Objective-C++ is a superset of C++, just as Objective-C is a superset of C. In Objective-C++, you can make objc-style message passing calls (like [some-objc-object callMethod];) from within a C++ function. Conversely, you can call C++ functions from within ObjC code like:

@interface MyClass {
MyCPPClass *cppInstance;
}
@end

@implementation MyClass
- (id)init {
if(self = [super init]) {
cppInstance = new MyCPPClass();
}
return self;
}
- (void) dealloc {
if(cppInstance != NULL) delete cppInstance;
[super dealloc];
}
- (void)callCpp {
cppInstance->SomeMethod();
}
@end

You can find out more about Objective-C++ in the Objective-C language guide. The view layer can then be pure Objective-C.

The second option is to use a cross-platform C++ toolkit. The Qt toolkit might fit the bill. Cross-platform toolkits are generally despised by Mac users because they do not get all the look and feel details exactly right and Mac users expect polish in the UI of Mac applications. Qt does a surprisingly good job, however, and depending on the audience and the use of your app, it may be good enough. In addition, you will lose out on some of the OS X-specific technologies such as Core Animation and some QuickTime functionality, though there are approximate replacements in the Qt API. As you point out, Carbon will not be ported to 64-bit. Since Qt is implemented on Carbon APIs, Trolltech/Nokia have had to port Qt to the Cocoa API to make it 64-bit compatible. My understanding is that the next relase of Qt (currently in release candiate) completes this transition and is 64-bit compatible on OS X. You may want to have a look at the source of Qt 4.5 if you're interested in integrating C++ and the Cocoa APIs.


ⁱ For a while Apple made the Cocoa API available to Java, but the bridge required extensive hand-tuning and was unable to handle the more advanced technologies such as Key-Value Bindings described above. Currently dynamically typed, runtime-bound languages like Python, Ruby, etc. are the only real option for writing a Cocoa app without Objective-C (though of course these bridges use Objective-C under the hood).

.c files instead of .m in Objective-C projects?

The primary benefit is that .c files can be used as-is in normal C programs and you know they won't accidentally incorporate Objective-C constructs that render them incompatible.

Cocoa Programming in C?

Just learn Objective-C. It isn't that hard; much, much, simpler than, say, C++. The object model is extremely similar to Java or SmallTalk.

The entire Cocoa stack of APIs are all in Objective-C, the documentation is all in Objective-C, many of the design patterns (KVO, KVC, delegation) are inherently Objective-C isms and all of the examples are Objective-C.

You are going to have to have a working knowledge of Objective-C to effectively program the system anyway. Any attempts to avoid Objective-C is just going to make your job harder, yield less maintainable code, and vastly reduce the # of folks in the community who can help.

What's the difference between Objective-C and Cocoa?

Objective-C is the language... it defines all the things like the keywords for defining objects, the syntax for messaging object, things like that.

Cocoa is a development framework (it's actually an umbrella framework which combines three other frameworks, Foundation, AppKit and CoreData).

These frameworks (Cocoa) define all the objects that are nice to use and interact with the operating system, as well as a number of functions. For example, Cocoa defines things like NSString and NSObject. Cocoa can currently be used with other language bindings, such as python or ruby, and used to be used with Java as well. So, if you were using Cocoa with Java, you would still get an NSString object, but you would call and use it from within a Java application.

Without linking to one of the Cocoa frameworks, Objective-C comes with only a very basic Object class as a pre-defined root class.

What’s the difference between Xcode, Objective-C and Cocoa?

Objective-C is a programming language. It could be said that it’s just a description of what valid Objective-C programs look like and what they mean. If you have a source code listing written in Objective-C, you need an interpreter or a compiler to put the listing to work. Languages like Objective-C are usually compiled, so most people use a compiler (like LLVM). Objective-C is almost exclusively used to develop for iOS and OS X, but there are other uses, too – as an example, some people write Objective-C for Linux.

You can use a text editor to write the sources and a compiler to turn them into an actual programs, but with modern technologies there’s much more to take care of, so that there is another program to make your job easier. These are called Integrated Development Environments, or IDEs. An IDE offers you a convenient way to edit the sources, compile them, debug the resulting programs, read the documentation, and many other things. Xcode is one such IDE. An important observation here is that Xcode does not compile your sources itself, it just calls the standalone compiler (LLVM). And Xcode is not the only IDE you can use to develop Objective-C apps – there’s AppCode, for example.

Writing iOS or OS X apps from scratch each time would be very time-consuming. That’s why Apple provides the developers with a good set of libraries. The libraries are simply a huge amount of source code written by Apple, and this source code takes care of most things that apps have in common. These libraries are called Cocoa.

Now, if you can’t figure out how to extend a class, you are most probably talking about Objective-C. It doesn’t have anything to do with Xcode or Cocoa, you could be very well writing some GNUstep code for Linux using Vim as an IDE and GCC as a compiler. On the other hand, if your Xcode build process fails because of some mysterious setting, or if you’re trying to build a static library in Xcode, that’s clearly an Xcode issue. And if you can’t figure out how to use some NSObject facility or the NSFileManager class, that’s Cocoa. (But it doesn’t have to be Xcode-related, as you could use AppCode or TextMate as your IDE!)


Originally available on my blog. Feel free to link to the blog post or this question when retagging or explaining the difference.

How to call C++ method from Objective-C Cocoa Interface using Objective-C++

I found a solution by noting that there was an existing wrapper class CWrapper.h and it was an objective-C++ implementation class CWrapper.mm. There was a CMain variable instantiated as cmain. I made a getter method for x and I simply created a static method in the wrapper class + (void) passX:(int) number; that I called in the slider class. I chose a static method because this for this application, this value will never have to be different between objects. I hope I made the right choice here!

See code changes below:

I added this to the Slider.h file.

- (int)X;

I added the getter and [CWrapper passX:[self getX]]; to the updateSliderValue method in the Slider.mm file.

- (int)X {
return [slider intValue];
}

- (IBAction)updateSliderValue:(id)sender {
[sliderValue setIntValue:[slider intValue]];
[CWrapper passX:[self getX]];
}

This is the code I added to CWrapper.h.

+ (void) passX:(int) number;

This is the code I added to CWrapper.mm.

+ (void) passX:(int)num
{
cmain.setValueofX(num);
}

Call a cocoa/obj-c method from a C++ dylib in MAC OS X

You actually have a plethora of options here.

  1. If the dylib is one of your own, you can compile it as Objective-C++ for Mac OS X and #ifdef the objective-C calls (or not if you are only targeting Mac OS)
  2. Both Obj-C and C++ can make use of C interfaces, so you could write an adapter layer in C (remember Obj-c is a strict superset of C) and expose it for the dylib to call the C functions which then call the Obj-C code.
  3. You can use Blocks, which work in C, C++, and of course Obj-C
  4. you can include the objective-c runtime (see documentation) and muck with that (This is where you would use the *IMP thing you mentioned).
  5. Yet another option might be to use Objective C++ from the Cocoa side to setup C++ objects and expose those to the dylib. How you would go about this really depends on what the library is and how it is used etc; we need to know more about the dylib and how it is being used to elaborate on this.

Since you specifically mention using an IMP lets talk a bit more in depth about that. The declaration is typedef void (*IMP)(id self, SEL _cmd, ...); which you can see takes a pointer to an Obj-C objects, and a SEL (selector), which is just a special C-String representation of the method. You can read more about both SEL and IMP in the documentation.

You can also make use of the runtime's C functions such as objc_msgSend to call a method by passing a pointer to the object and a SEL just like with IMP.

This should be enough information to get you started. Thanks for this question BTW, I never really sat down and thought about all the possible ways to combine C++ with Objective-C before. Odds are I even missed something ;)

Cocoa or Objective-C?

You've got it a little wrong.

NSTimer, NSString, NSMutableArray are all Cocoa. int and float are actually C, but since Objective-C is a strict superset of C, you are able to use them in your Objective-C code.

Pure Objective-C requires linking only to the Objective-C runtime library and no other frameworks or libraries. Cocoa is a framework that includes things like NSObject and NSString. Other frameworks, like AppKit, extend the Cocoa framework.

Coding in pure Objective-C usually means deriving from the root object called Object and not NSObject. Things like @implementation, @interface, @selector etc. are the Objective-C extensions to C and these are what are common in all Objective-C source, pure or not. If you want to code in pure Objective-C you cannot use anything other than your own objects derived from Object.

#import <objc/Object.h>


Related Topics



Leave a reply



Submit