44

I'm trying to mix Objective-C with C++. When I compile the code, I get several errors.

A.h

#import <Cocoa/Cocoa.h> #include "B.h" @interface A : NSView { B *b; } -(void) setB: (B *) theB; @end 

A.m

#import "A.h" @implementation A - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } - (void)drawRect:(NSRect)dirtyRect { // Drawing code here. } -(void) setB: (B *) theB { b = theB; } @end 

B.h

#include <iostream> class B { B() { std::cout << "Hello from C++"; } }; 

Here are the errors:

/Users/helixed/Desktop/Example/B.h:1:0 /Users/helixed/Desktop/Example/B.h:1:20: error: iostream: No such file or directory /Users/helixed/Desktop/Example/B.h:3:0 /Users/helixed/Desktop/Example/B.h:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'B' /Users/helixed/Desktop/Example/A.h:5:0 /Users/helixed/Desktop/Example/A.h:5: error: expected specifier-qualifier-list before 'B' /Users/helixed/Desktop/Example/A.h:8:0 /Users/helixed/Desktop/Example/A.h:8: error: expected ')' before 'B' /Users/helixed/Desktop/Example/A.m:26:0 /Users/helixed/Desktop/Example/A.m:26: error: expected ')' before 'B' /Users/helixed/Desktop/Example/A.m:27:0 /Users/helixed/Desktop/Example/A.m:27: error: 'b' undeclared (first use in this function) 
3
  • 2
    Don't forget that you force users of your ObjC class to use ObjC++ if you put C++ includes in the header - use opaque pointers to avoid that. Commented Apr 26, 2010 at 0:33
  • @gf So how would you recommend doing this then? Should I just use a void pointer, or can I use an id type? Commented Apr 26, 2010 at 2:05
  • 1
    To avoid losing type safety i personally prefer forward declared structs (stackoverflow.com/questions/2262011/…) but have also seen "private" ObjC classes (i.e. via id instance variables). Commented Apr 26, 2010 at 4:36

5 Answers 5

80

You need to name your .m files .mm. And you will be able to compile C++ code with Objective-C.

So, following your example, your AView.m file should be named AView.mm. It's simple as that. It works very well. I use a lot of std containers (std::vector, std::queue, etc) and legacy C++ code in iPhone projects without any complications.

Sign up to request clarification or add additional context in comments.

1 Comment

What is I can't rename the .m file to .mm due to other classes that will report an error if I use .mm extension. Any other solution is mind?
5

Never mind, I feel stupid. All you have to do is rename AView.m to AView.mm so the compiler knows it's Objective-C++, and it compiles without a problem.

2 Comments

I'm just glad it was that simple, since now I can use YOUR code as a template for trying this crap out myself!
There is another way to do it -- in the file attributes window (forget what it's called -- the right-hand window when clicked on a file in Navigator) you can set the type of the file independent of its file extension.
2

you could keep the interface cleaner with forward declaration of C++ classes:

#import <AnObjCclass.h> class DBManager; // This is a C++ class. NOTE: not @class @interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate, MFMailComposeViewControllerDelegate> { DBManager* db; ... } 

1 Comment

This doesn't answer the question. It is about code style and has nothing to do with the compiler errors reported in the question. It should have been a comment.
1

I am sharing some of the points that I understood on this topic.

We can mix both .cpp and .m files with a pure C interface. As we know the Clang compiler will support C++, Objective C as well as Objective C++, it might be a better means for mixing these languages.

One thing when mixing these languages to be taken care is using the header files. We can keep the C++ out of our Objective C headers by declaring the Cpp objects in class extensions.

Alternatively we can declare the cpp objects just at the start of @implementation block in our Objective Cpp(.mm) file.

Managing the memory will be a concern when we are dealing with Cpp objects. We can allocate memmory for an object using ‘new’ and release the memory by calling ‘delete object’. Normally if we are using ARC, we need not be aware of releasing the memory for an object.

While using the cpp classes, we can declare a Cpp object in two ways say CppWrapper wrapper and CppWrapper *wrapper where CppWrapper is a Cpp class. When we are using the latter the programmer is responsible for managing the memmory.

Another main thing is that when we are calling an objective C method with parameters, we are passing the references, while in cpp we need to pass the parameters by reference by using the ‘&’ keyword, otherwise copy of the object is been passed.

Deallocation of Objective C object is handled at runtime, where when ‘delete’ is invoked to an Cpp object, it will no longer remains in the memory.

When writing Cpp, we have shared pointer and weak pointers which is similar to the strong and weak in Objective C.

http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++ http://www.raywenderlich.com/62989/introduction-c-ios-developers-part-1

Comments

0

In situations where you wish to introduce a simple C++ function like std::cout << then Hot Licks offers a good alternative.

Change the "Identity and Type" From: Objective-C source To: Objective-C++ source

The .mm extension simply identifies the file type; and then you are seeking a Objective-C++ not a Objective-C type.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.