16

I have a .cpp/.hpp file combo -> the .hpp file has #include ..

I also have a .mm/.h file combo -> if I include the .hpp file within my .mm Objective C++ file, there are no issues. However, if I try to include the .hpp file within my .h (Objective C header) file, I get a preprocessor issue 'iostream not found'.

Is there any way around this other than doing funky stuff like having a void* in my Objective C .h file and then casting it as the type that is included in the .mm or wrapping every C++ type within an Objective C++ type?

My question is basically the same as Tony's question (but nobody answered his):

https://stackoverflow.com/questions/10163322/how-to-include-c-header-file-in-objective-c-header-file

Community
  • 1
  • 1
fatfreddyscat
  • 835
  • 3
  • 8
  • 26
  • 1
    You have to avoid any C++ includes/code in your header for your file to be included in other non Objective-C++ classes. This means you may need to use void* to store member variables. – Joe Dec 03 '12 at 20:59
  • You are asking is there a valid way for compiler of language A to compile language B. Usually no. Objective-C can use C code. Objective-C++ code can use C++ code. But C and C++ are different languages so keep them apart very strictly. – Martin York Dec 03 '12 at 21:09
  • @LokiAstari - Actually, that isn't what I was asking -> I'm using only Objective C++ and C++. My C++ includes iostream (e.g. C++) and my Objective C++ header file can't include my C++ header file since that header file include iostream. – fatfreddyscat Dec 03 '12 at 21:43
  • @Joe - thanks for your answer; if you put it as an answer, I'll mark it as accepted. However, I *definitely* wish there was a better way that using void* and casting everywhere... :/ – fatfreddyscat Dec 03 '12 at 21:44
  • 2
    @fatfreddyscat I've got something better.. an [answer](http://stackoverflow.com/a/2262395/418715) using opaque pointers. – Joe Dec 03 '12 at 21:48
  • @Joe -> you are a god!!! Please put that as an answer and I will accept it as the solution. – fatfreddyscat Dec 03 '12 at 22:05

3 Answers3

26

The problem is that you have to avoid all C++ semantics in the header to allow normal Objective-C classes to include it. This can be accomplished using opaque pointers.

CPPClass.h

class CPPClass
{
public:
    int getNumber()
    {
        return 10;
    }
};

ObjCPP.h

//Forward declare struct
struct CPPMembers;

@interface ObjCPP : NSObject
{
    //opaque pointer to store cpp members
    struct CPPMembers *_cppMembers;
}

@end

ObjCPP.mm

#import "ObjCPP.h"
#import "CPPClass.h"

struct CPPMembers {
    CPPClass member1;
};

@implementation ObjCPP

- (id)init
{
    self = [super init];
    if (self) {
        //Allocate storage for members
        _cppMembers = new CPPMembers;

        //usage
        NSLog(@"%d", _cppMembers->member1.getNumber());
    }

    return self;
}

- (void)dealloc
{
    //Free members even if ARC.
    delete _cppMembers;

    //If not ARC uncomment the following line
    //[super dealloc];
}

@end
Joe
  • 56,979
  • 9
  • 128
  • 135
  • This is a great response! Helped me out just now! – ruoho ruotsi Feb 20 '15 at 05:59
  • I have the problem of objective-c++ header creep. If I have an objective-c++ wrapper class, its header includes C++ headers. And then I wish to use this wrapper object in other objective-c code, I import the wrapper class header which inturn includes the c++. Therefore requiring all my classes to become objective-c++. How do you stop this? – silicontrip Feb 10 '21 at 05:27
4

To use C++ in an Objective-C++ header file make sure to:

  1. Have a .h/.mm couple (Objective-C++)
  2. In the identity of your file, have the type set to Objective-C++ Source (it should be automatic)
  3. Include the considered file only from Objective-C++ source files. This point is obvious but can be very quickly forgotten and hard to track down
MartinMoizard
  • 6,600
  • 12
  • 45
  • 75
0

The #include directive simply includes text; the only time Objective C will complain is if there is something in the include file that is not valid Objective C.

In your case, it gives you the answer; the iostream.h header file is not found in Objective C. Find where this file is referenced and remove the #include to it.

RonaldBarzell
  • 3,822
  • 1
  • 16
  • 23
  • unfortunately, I can't remove the #include in the .hpp file as it uses certain types in iostream.. – fatfreddyscat Dec 03 '12 at 21:01
  • Well, here's a thread on this that seems to indicate a work-around: http://stackoverflow.com/questions/3794931/iostream-and-sstream-for-objective-c – RonaldBarzell Dec 03 '12 at 21:02
  • -> thanks for the response but unfortunately that doesn't work for me as I am including my .hpp within the Objective C++ .h file; I tried renaming the .h to .mm and importing that instead but that didn't work. I also tried moving the stuff from the Objective C++ .h file into the .mm file but that didn't work either (and of course wouldn't be helpful in the long run). – fatfreddyscat Dec 03 '12 at 21:47
  • You could do what the c people have been doing for years and `#ifdef (__cplusplus)` – CodaFi Dec 03 '12 at 22:10
  • Joe's answer (comment on original question) works best for me: http://stackoverflow.com/a/2262395/418715 – fatfreddyscat Dec 03 '12 at 22:36