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();
}
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
Winder
  • 1,984
  • 5
  • 23
  • 33

4 Answers4

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
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
  • 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. – Winder Feb 14 '10 at 20:33
  • 2
    I'd always prefer opaque pointers over casts - it might be a bit more work, but you get full type safety back. – Georg Fritzsche Feb 14 '10 at 20:41
  • 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: http://robnapier.net/blog/wrapping-c-objc-20 – Rob Napier Feb 20 '10 at 16:44
  • *Note:* Rob Napier posted a nice [update](http://robnapier.net/blog/wrapping-c-take-2-1-486) on wrapping C++. – Georg Fritzsche Oct 17 '10 at 23:07
  • 1
    thanks a million for this code example. I was 2 steps shy of throwing my mac out the window. – dubbeat Sep 07 '11 at 14:07
  • @GeorgFritzsche dont we have to initialize the c++ class to create an object in opaque pointer ?? i was using the above example but got exc_bad_access in first class method access .. – sujat Apr 23 '15 at 03:46
  • @shishir123 Sure, that is why there is the placeholder comment for _"... create opaque member on initialization"_. – Georg Fritzsche Apr 23 '15 at 11:09
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++

oefe
  • 19,298
  • 7
  • 47
  • 66
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
pizzamonster
  • 1,141
  • 10
  • 9
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.

JanX2
  • 1,303
  • 1
  • 12
  • 19
Martin Cote
  • 28,864
  • 15
  • 75
  • 99