如何正确处理Cocoa Touch中的前向声明/ #import(Objective-C跨C++)?

3

我正在尝试编写这个头文件:

//@class AQPlayer;

//#import "AQPlayer.h"

@interface AQ_PWN_iPhoneViewController : UIViewController {

    AQPlayer* player;
}

@end

AQPlayer是一个用C++编写的.mm文件。

我试图在这里进行类的前向声明,但它对我抱怨:

错误:找不到“AQPlayer”的接口声明

所以我尝试“#import”头文件,但它投诉了一些完全不同和奇怪的东西。这里是一个错误投诉的片段:

从文件中包含

/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

我有点不明白,我不能为这个做一个前向声明吗?

4个回答

3

通常的做法如下:

// 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

你看到的严重错误可能是因为编译器试图将 AQPlayer.h 解析为 Objective-C 而不是 Objective-C++。你可能需要对导入 AQPlayer 的所有源文件使用 .mm,即使该特定类不使用 C++。


1

我已经将我的AQ_PWN_iPhoneViewController文件改为.mm文件。所以,不,那并不能解决它。

这里有更多信息:如果我尝试调用AQPlayer实例的方法/函数,将会显示错误“error: cannot find interface declaration for 'AQPlayer'”。以下是一个示例:

- (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];

}

移除任何类似StartQueue的函数调用将使错误消失,但我确实需要调用该方法!


你应该编辑你的原始问题,而不是把这个作为答案发布。话虽如此,AQPlayer是一个 obj-c 或 C++ 类吗? 你给出的前向声明 @class AQPlayer; 是针对 Obj-C 的,但你的方法调用 player->StartQueue(false); 是 C++ 语法。 你要么需要在 C++ 中使用 class AQPlayer;,要么在 Obj-C 中使用 [player startQueue:NO]; - Daniel Dickison

1

我也遇到了完全相同的问题(尝试重用苹果“SpeakHere”演示中的AQPlayer c++类)。

似乎编译器会混淆并尝试将objective-c++编译为objective-c(因此出现所有错误)。我通过右键单击导入mm文件的m文件并选择“获取信息”,然后将文件类型更改为“sourcecode.cpp.objcpp”来使其编译成功。


0
首先,您必须告诉编译器一个文件包含C++代码(包括一个包含C++代码的文件!)。您可以通过将其重命名为.mm扩展名(.h保持不变)来实现此目的。第二种方法是将文件类型设置为“sourcecode.cpp.objcpp”,就像Atomoil所说的那样。
另外,如果您想要C++类的前向声明,您应该使用“class AQPlayer;”,而不是“@class AQPlayer;”。如果您这样做,您将会得到一个“无法找到XXX接口声明”的错误。
我通常在.h文件中包含C++文件,从而消除了前向声明的需要,尽管有时您可能不想这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接