Reputation: 125
I'm fairly new to Objective-C and I am building an iCloud utility library for our project. I have created an iCloud utility class in Objective-C. I've noticed there are loads of questions on using C++ classes in Objective-C but few the other way around. The problem is, our project (and engine on top of which our project is built) is entirely written in C++ and as such, the objective-c icloud class I have written needs to be accessable from a C++ interface I am writing.
Here is an example:
#import <Foundation/Foundation.h>
@interface iCloudUtil : NSObject
@property(nonatomic, assign, getter=isAvailable) BOOL iCloudIsAvailable;
@property (assign) NSString *urlToFile;
-(bool) init_iCloud;
-(void) loadDocument: (NSString*)fileUrl;
@end
#import "iCloudUtil.h"
@synthesize urlToFile = _urlToFile;
@synthesize iCloudIsAvailable = _iCloudIsAvailable;
//////////////////////////////////////////////////////
@implementation iCloudUtil
-(bool) init_iCloud{
//blah blah
}
-(void) loadDocument: (NSString*)fileUrl{
//more blah blah
}
@end
The C++ class I'm attempting to use this from is like so:
#ifndef __ICloudInterface__
#define __ICloudInterface__
class ICloudInterface {
static ICloudInterface *_instance;
bool iCloudIsAvailable;
public:
ICloudInterface();
~ICloudInterface();
bool init_iCloud();
};
#endif
What I want to do is to be able to create an instance of iCloudUtils in my C++ class, but I can't #include it in my c++ class without getting 200+ errors about "Stray '@' in program". I'm very inexperienced with Objective-C and even less so with mixing it with C++ so could someone help me out with advice on how to achieve this?
Edit: Just to clear it up, i have already attempted to rename the .cpp to .mm but this hasn't fixed the problem.
Edit2: Also, from what I have understood with reading up (please correct me if I am wrong) by changing a file to .mm, any file that includes it must also change to .mm. I can't do this since it would require changing a very very large number of files to suit a single optional class (reminder that this project and its engine are ALL c++ and this is a cross-platform engine and project).
Upvotes: 4
Views: 2904
Reputation: 2393
Switch your .cpp filenames to .mm - this takes it from c++ to objective-c++. Then you'll be compiling a language that understands the header.
Upvotes: 2
Reputation: 2953
Sure -- you can do this. The main thing that's required is to set the .CPP file as "Objective-C++ Source" -- the ".mm" convention is an automagic nicety, but not required. You can then mix and match pretty much as you please:
#import <Foundation/Foundation.h>
#include <iostream>
@interface iCloudUtil : NSObject
@property(nonatomic, assign, getter=isAvailable) BOOL iCloudIsAvailable;
@property(assign) NSString *urlToFile;
- (bool) init_iCloud;
- (void) loadDocument:(NSString*)fileUrl;
@end
//////////////////////////////////////////////////////
@implementation iCloudUtil
@synthesize urlToFile = _urlToFile;
@synthesize iCloudIsAvailable = _iCloudIsAvailable;
- (bool) init_iCloud {
NSLog(@"init_iCloud");
std::cout << "i can mix std c++ in here as well\n";
return YES;
}
- (void) loadDocument:(NSString*)fileUrl {
NSLog(@"url is %@",fileUrl);
}
@end
//////////////////////////////////////////////////////
class ICloudInterface {
static ICloudInterface* _instance;
bool iCloudIsAvailable;
iCloudUtil* myCloudUtil;
public:
ICloudInterface();
~ICloudInterface();
bool init_iCloud();
};
ICloudInterface::ICloudInterface() {
std::cout << "ICloudInterface::ctor\n";
myCloudUtil = [[iCloudUtil alloc] init];
[myCloudUtil init_iCloud];
[myCloudUtil loadDocument:@"file://foo/bar/baz"];
}
ICloudInterface::~ICloudInterface() {
[myCloudUtil release], myCloudUtil = nil;
std::cout << "ICloudInterface::dtor\n";
}
int main(int argc, const char * argv[]) {
std::cout << "Test objc/objc++\n";
ICloudInterface iface;
return 0;
}
Upvotes: 1
Reputation: 22042
You can't use Obj.C class objects in C++ file with file extension .cpp
You can use c++ class in Obj.C class with extension .mm
To communicate between C++ & Obj.C class, write helper c++ class in .mm file
Say:
interface iCloudUtil : NSObject // in .m file
class ICloudInterface //in cpp file.
You can take bridge class help to communicate between cpp class in .cpp file to obj.C class in .m file.
//include iCloudUtil.h only in ICloudBridge.mm file.
class ICloudBridge {
static ICloudBridge *_instance;
public:
ICloudBridge();
~ ICloudBridge();
ICloudBridge *sharedICloudBridge();
void loadDocument();
};
void ICloudBridge:: loadDocument()
{
iCloudUtil *obj = [iCloudUtil alloc] init] autorelese];
[obj loadDocument:@"DocName"];
}
in ICloudInterface.cpp
ICloudBridge *bridge = ICloudBridge::sharedICloudBridge();
bridge-> loadDocument();
Upvotes: 2
Reputation: 17655
I think you have to use .mm
extension instead of .m
extension in the source code filename, or set the file to compile as Objective-C++ in Xcode.
Upvotes: 1