18

I'm trying to mix C++ and Objective-C, I've made it most of the way but would like to have a single interface class between the Objective-C and C++ code. Therefore I would like to have a persistent C++ object in the ViewController interface.

This fails by forbidding the declaration of 'myCppFile' with no type:

#import <UIKit/UIKit.h>
#import "GLView.h"
#import "myCppFile.h"

@interface GLViewController : UIViewController <GLViewDelegate>
{
    myCppFile cppobject;
}

@end

However this works just fine in the .mm implementation file (It doesn't work because I want cppobject to persist between calls)

#import "myCppFile.h"
@implementation GLViewController
- (void)drawView:(UIView *)theView
{
    myCppFile cppobject;
    cppobject.draw();
}

4 Answers 4

29

You should use opaque pointers and only include C++ headers in the file that implements your Objective-C class. That way you don't force other files that include the header to use Objective-C++:

// header:
#import <UIKit/UIKit.h>
#import "GLView.h"

struct Opaque;

@interface GLViewController : UIViewController <GLViewDelegate>
{
    struct Opaque* opaque;
}
// ...
@end

// source file:
#import "myCppFile.h"

struct Opaque {
    myCppFile cppobject;
};

@implementation GLViewController
// ... create opaque member on initialization

- (void)foo
{
    opaque->cppobject.doSomething();
}
@end
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks, the other suggestions didn't seem to work and I ended up declaring my object as an "id*" then casting it to the correct type everywhere I wanted to use it. This seems like the same idea, but is much cleaner since I don't have to do all the extra casts.
I'd always prefer opaque pointers over casts - it might be a bit more work, but you get full type safety back.
I've been playing with opaque pointers for this, which I use extensively for C/C++ wrapping, but so far I haven't seen the real benefit. Can you compare this style (along with some code showing how "opaque" is allocated and released) to the void* based style here: robnapier.net/blog/wrapping-c-objc-20
Note: Rob Napier posted a nice update on wrapping C++.
thanks a million for this code example. I was 2 steps shy of throwing my mac out the window.
|
3

Make sure that all files that include GLViewController.h are Objective-C++ sources (*.mm).

When you include C++ code in the header of your view controller, all sources that import this header must be able to understand it, so they must be in Objective-C++

Comments

2

You need to declare the C++ objects in an interface block in your .mm file.

In .mm:

#include "SomeCPPclass.h"

@interface SomeDetailViewController () {
    SomeCPPclass*    _ipcamera;
}
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)blabla;
@end

1 Comment

Take close note of the () - that's the black(et) magic that makes this work :)
0

I think you need to set the following flag to true in your project settings:

GCC_OBJC_CALL_CXX_CDTORS = YES

This should allow you to instantiate C++ objects in your Objective-C classes.

1 Comment

This didn't seem to work. I'm using Xcode 3.2.1 and the 3.0 iphone SDK.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.