Wrapping C++ Final Edition
I have always strong recommended segregating Objective-C and C++ code with a thin Objective-C++ wrapper. I do not like Objective-C++. It is useful for what it does, but it is a mess of a “language.” It has many downsides, for slower compiles and poor debugging facilities, to confusing code and inefficient ARC code. .mm is a blight on your code. Never let it spread.
That said, Objective-C++ is invaluable for integrating C++ into Objective-C. And while I am not a great lover of C++, it is a very useful language and there is a great deal of excellent code written in it that is well-worth reusing in your Cocoa projects. Many of Apple’s frameworks are implemented in C++.
So my recommendation for those who have existing C++ logic code has always been thus: write your UI in pure Objective-C (.m). Write your “middleware” in pure C++ (.cpp). And have a thin Objective-C++ (.mm) wrapper layer to glue them together. Your ObjC++ API should ideally exactly match your C++ API, just converting types (for instance converting std::string to and from NSString).
(As a side note, I also recommend that OS-related things like file management, network management, and threading all be handled natively. GCD is much better than pthreads. NSURLConnection is much better than writing your own C++ networking layer in BSD sockets. But this is tangental to the main point.)
Saying all that, how do you wrap a C++ object so that Objective-C can read it? This used to be a question that required some significant thought. See Wrapping C++, Take 2 Part 1 and Part 2 for my previous thinking on the subject.
Improvements in Objective-C have made all of the previous hoop-jumping irrelevant. The problem all my previous solutions was trying to solve was that you had to declare ivars in the header. Your ivar was a C++ class (which might be in a namespace or might be a template), and that made it difficult to declare in the header without forcing all the importers to be ObjC++. So to solve this generally you needed opaque types, or at the very least forward declared structs, etc. And it was all a big pain.
But that’s over. You can now declare all your ivars in the implementation file. So everything’s easy. Your wrapper class can have C++ ivars without having any impact on users of the wrapper class.
Consider a simple C++ class (but throwing in the headache of a namespace):
namespace MY {
class Cpp {
public:
std::string getName() { return _name; };
void setName(std::string aName) { _name = aName; };
private:
std::string _name;
};
}
The wrapper for this is trivial:
@interface CPPWrapper : NSObject
@property (nonatomic, readwrite, copy) NSString *name;
@end
@interface CPPWrapper ()
@property (nonatomic, readwrite, assign) MY::Cpp *cpp;
@end
@implementation CPPWrapper
@synthesize cpp = _cpp;
- (id)init {
self = [super init];
if (self) {
_cpp = new MY::Cpp();
}
return self;
}
- (void)dealloc {
delete _cpp;
}
- (NSString *)name {
return [NSString stringWithUTF8String:self.cpp->getName().c_str()];
}
- (void)setName:(NSString *)aName {
self.cpp->setName([aName UTF8String]);
}
@end
Couldn’t be easier really. The one headache that really remains in my experience is enums inside of a namespace (or more generally enums declared in a C++ header). The best solution is to use #if __cplusplus blocks to strip away the namespace and still declare the enum in pure C. Do this if at all possible. Otherwise you’ll wind up with an C enum that mirrors the C++ enum. This is a maintenance nightmare, since changes to the C++ enum will often be missed in the ObjC enum, and you’ll get very difficult-to-debug errors with enum mismatches.
Just to ask and answer a possible question: why *Cpp and not just Cpp? The reason is that in almost all cases the C++ object will be created outside of your wrappers. So in almost all cases, there’s going to be a method like initWithCpp:(Cpp *)cpp. How does that work? Easy, wrap it in #if __cplusplus:
#if __cplusplus
#include "Cpp.h"
...
- (CppWrapper *)initWithCpp:(Cpp *)cpp;
#endif
Anyway, most of my research into opaque types and generally how to manage C++ wrappers has now become trivial. I’m just giving one more post to let you all know that. (And because Orpheus asked.) Post comments if there are more questions.

Hello, and thanks for the great info! However, I do have one question: how would I go about doing the reverse of this? IE, calling a Objective-C function from C++?
First, when possible, avoid the ObjC entirely. Many ObjC things can be done in Core Foundation, which is C and so directly usable in C++.
But sometimes you have to call ObjC. In that case, you work in reverse. You create an C++ wrapper object. In its header, I recommend using a void* to hold a pointer to the wrapped ObjC object. You can’t put the ObjC object into a struct if ARC is enabled, but you can use CFBridgingRetain() and CFBridgingRelease() to correctly memory manage the void. You can typedef void to some other name to improve documentation.
Hi Rob,
Excellent article, and highly useful. However, I have a question? I need to write my library in C++ so that it remains cross-platform, and works on windows 8 as well. I’m following exactly your approach, i.e UI in .m files, and library in C++. In order to create a library in C++ that will run on iPhone, I am using the (BSD C) C/C++ library template for Mac OSX to create my library project. My header is contained in .h file whereas my implementation is contained in .cpp file. This project compiles fine individually, however, when I include this library in an iPhone application, I get an error message saying “Unknown type name ‘class’; did you mean ‘Class’?”, even though I’ve created a wrapper of .mm file separately which encapsulates the .cpp file implementation. I wasn’t able to get it to work, unless, I changed my compiler options for LLVM Clang v3.1 to compile sources as Objective-C++. Without this, I get the same error. I wanted to know is this the right way to get the .cpp files compiled or I may be missing something here? I would appreciate your help with this.
Many thanks, Asheesh
Complaining that it doesn’t know “class” and thinks you mean “Class” suggests that it’s trying to compile C++ as pure ObjC. That suggests that you have the word “class” in a .h file that is imported into an ObjC file, or you have marked a .cpp file as being Objective-C. You can check the former by looking for the “included in file” lines in the error. That will tell you which actual source file is involved. You can check the latter by opening the file inspector (the right-hand panel), and verifying the “File Type.” Make sure that all of your files are marked as “Default”. In particular, make sure you haven’t marked C++ file as “Objective-C Source” by accident.
Hello Rob,
Thank you for the great article. I’ve been reading your blog for months now and it has helped me tremendously with my first XCode project!
I have a question, however. In my current XCode project, I am using a C++ free source streaming library, and trying to implement a C++ function from this source code in a XCode UI interface to activate upon a button push. I imported the necessary source code header files into a .cpp file to make an object out of my target function (like your “class Cpp” example, but without the namespace), and I made a wrapper out of it, like your CPPWrapper example, but I’m confused as to the exact relationship the .cpp and the wrapper code has. I have my wrapper code in my AppDelegate.m. Is this the “implementation file” where it belongs, or should it be elsewhere? I am getting many parse and semantic errors on my wrapper code in the AppDelegate.m. Yet, when I include my .cpp into the AppDelegate.m (which I believe is incorrect anyway, based on prior comments), most AppDelegate.m issues are solved, yet the .cpp file gets the “Did you mean ‘Class’?” error that was discussed before, among others.
All my files are on type default also, FYI.
Could you please clarify where exactly the wrapper code should be in my case? Should I be including my .cpp object file anywhere at all…and if so, where? I’d appreciate any help–I am proficient in C++ but am very new to Objective C.
Your wrapper should be its own object. It definitely shouldn’t be in AppDelegate (almost nothing should be there except for delegate methods). The @interface goes in its own .h file and the @implementation goes in its own .m file. You never, ever include a .cpp file into anything.
Build a simple, stand-alone ObjC++ wrapper object around the C++ object. The ObjC++ object should have a pure ObjC header file, and a .mm implementation. It should generally have a one-to-one mapping of C++ object methods for ObjC methods.
@Rob Napier
Thank you for the prompt reply! I really appreciate it.
I will rearrange my code to mirror your solution.
Much thanks again,
Wow thanks so much for this. It really got me started!
I dont see you calling include “Cpp.h” in the Wrapper’s header. If I put it in my wrapper class and don’t import the wrapper class in objc anywhere, it builds fine. Once I import my wrapper class though, I get ‘iostream’ file not found. How do I import the objC++ wrapper file that includes the c++ file without that error?
Sorry, for all the comments, please remove the filehosting.org links. I didn’t realize they require your password to download.
https://github.com/saltzmanjoelh/ObjCPPTest
@Joel Saltzman You shouldn’t (can’t) import Cpp.h into CPPWrapper.h. Cpp.h is a C++ header. CPPWrapper.h is an ObjC header. The point of the wrapper is to shield ObjC callers from the C++ classes.
Hi Rob,
Great post, I’ve followed its advice for a C++ framework I’m working on right now. Something I was curious about: if the goal is to create a static library or framework which encapsulates some C++, is there anything that can be done about the requirement that the developer making use of the library or framework also link to the relevant C++ standard library either by -lstdc++ or by using the .mm suffix on the hosting class? It seems like it would be obligatory, but then I have the impression that some of the CoreAudio and AudioToolbox code is written in C++ (although maybe this isn’t correct) and linking those frameworks in an app doesn’t require doing anything about the C++ standard lib, so it got me wondering.
As I recall, you don’t need to explicitly include libc++, since it’ll get linked for various other reasons in almost all cases. But try it and see. The fact that CoreAudio uses C++ (and it does) but doesn’t require you to link libc++ isn’t relevant, however. Apple frameworks use dynamic libraries, which can include dependencies that are loaded at runtime. You can’t create a dynamic library on iOS, however, so your static library doesn’t get that benefit, and the final link step must include all dependencies (but libc++ is likely to get included anyway, so unless you’re getting errors, I wouldn’t add it).
Hmm, I do get errors, just about 40 of them, exclusively in the std namespace for a big all-C++ library (i.e. nothing else contained in the framework seems to cause any issues). The errors can be handled by the developer making use of the framework doing any of the following in their app:
As an experiment I tried adding some known-good basic_ios code to one of the methods of my wrapper and it resulted in those functions also appearing in my error list.
The last option above (just linking the dylib in the same step as the other dependencies) isn’t that onerous since I already need to inform the developer to add some dependencies there, but it would be great to have it be even simpler. Thanks for the info about the difference between the Apple dylibs and my static frameworks, that makes perfect sense.
Now I’m wondering if the issue isn’t that libc++ isn’t being loaded, but that a c++ stdlib is being loaded in the app but it doesn’t exactly match the one I compiled with, and setting it explicitly fixes that in some way. 40 functions seems like too few to represent every standard library function used in the framework, so it could just be those where the signature diverges.