Tutorial :How to deal with forward declaration / #import in Cocoa Touch (Objective-C cross C++) correctly?



Question:

I am trying to write this header file:

//@class AQPlayer;    //#import "AQPlayer.h"    @interface AQ_PWN_iPhoneViewController : UIViewController {        AQPlayer* player;  }    @end  

AQPlayer is a .mm file written in C++.

I tried to make a class forward declaration here, but it complains to me:

error: cannot find interface declaration for 'AQPlayer'

So I tried to "#import" the header file instead, but it complains something completely off and weird. Here's a slice of the error complained:

In file included from

/Users/akaraphan/Desktop/SpecialTopic1/AQ_PWN_iPhone/Classes/AQPlayer.h:51,                   from /Users/akaraphan/Desktop/SpecialTopic1/AQ_PWN_iPhone/Classes/AQ_PWN_iPhoneViewController.h:12,                   from /Users/akaraphan/Desktop/SpecialTopic1/AQ_PWN_iPhone/Classes/AQ_PWN_iPhoneAppDelegate.m:10:  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:78: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'CAStreamBasicDescription'  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:230: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:231: error: expected '=', ',', ';', 'asm' or '__attribute__' before '==' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:233: error: expected '=', ',', ';', 'asm' or '__attribute__' before '!=' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:234: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<=' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:235: error: expected '=', ',', ';', 'asm' or '__attribute__' before '>=' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:236: error: expected '=', ',', ';', 'asm' or '__attribute__' before '>' token  /Developer/Examples/CoreAudio/PublicUtility/CAStreamBasicDescription.h:239: error: expected ';', ',' or ')' before '&' token  

Am I missing something? Can't I do a forward declaration for this?


Solution:1

The normal way to do this would be:

// In your .h file...  @class AQPlayer;  @interface AQ_PWN_iPhoneViewController : UIViewController {      AQPlayer *player;  }  @end    // In your .mm file (see below why it has to be .mm instead of .m)...  #import "AQ_PWN_iPhoneViewController.h"  #import "AQPlayer.h"  @implementation AQ_PWN_iPhoneViewController  ...  @end  

The heavy duty errors you see is probably because the compiler is trying to parse AQPlayer.h as Objective-C instead of Objective-C++. You'll probably have to use .mm for all of your source files that imports AQPlayer, even if that particular class doesn't use C++.


Solution:2

I already made my AQ_PWN_iPhoneViewController to be a .mm file. So no, that doesn't fix it.

here's some more info: The error "error: cannot find interface declaration for 'AQPlayer'" will be shown if I tried to call a method/function of the AQPlayer instance. Here's an example:

- (void)viewDidLoad {

CFStringRef ref = (CFStringRef)[NSTemporaryDirectory() stringByAppendingPathComponent: @"1.mp3"];  player = new AQPlayer(&ref);    OSStatus result = player->StartQueue(false);    if (result == noErr)      [[NSNotificationCenter defaultCenter] postNotificationName:@"playbackQueueResumed" object:self];  

}

Removing any function call like StartQueue will make the error go away, but I do need to call the method!


Solution:3

I was also getting exactly the same issue (also trying to reuse the AQPlayer c++ class from the Apple "SpeakHere" demo).

Seems the compiler gets confused and tries to compile objective-c++ as objective-c (hence all the errors). I managed to get it to compile by right clicking on the m file that imports the mm file and selecting 'getInfo', then changing the filetype to "sourcecode.cpp.objcpp"


Solution:4

Firstly, you have to tell the compiler that a file has C++ code (a file including a file with C++ code also!). You can do this by renaming it to a .mm extension (.h stays the same). Second way is to set the file type to 'sourcecode.cpp.objcpp' like Atomoil said.

Also, if you want forward declaration for a C++ class you use 'class AQPlayer;', not '@class AQPlayer;'. If you do, you will get a 'cannot find interface declaration for XXX' error..

I usually include C++ files in the .h file, eliminating the need for forward declaration, although sometimes you don't want to do this.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »