Как правильно работать с форвардным объявлением / #import в Cocoa Touch (Objective-C cross C ++)?

Я пытаюсь написать этот заголовочный файл:

//@class AQPlayer;

//#import "AQPlayer.h"

@interface AQ_PWN_iPhoneViewController : UIViewController {

    AQPlayer* player;
}

@end

AQPlayer - это файл .mm, написанный на C ++.

Я попытался сделать здесь прямое объявление класса, но он жалуется мне:

error: cannot find interface declaration for 'AQPlayer'

Поэтому я попытался вместо этого "импортировать" заголовочный файл, но он жалуется на что-то совершенно странное и странное. Вот фрагмент ошибки, на которую пожаловались:

В файле, включенном из

/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

Я что-то упускаю? Разве я не могу сделать предварительное заявление по этому поводу?


person Community    schedule 22.07.2009    source источник


Ответы (4)


Обычный способ сделать это:

// 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 ++. Вероятно, вам придется использовать .mm для всех ваших исходных файлов, которые импортируют AQPlayer, даже если этот конкретный класс не использует C ++.

person Daniel Dickison    schedule 22.07.2009

Я уже сделал свой AQ_PWN_iPhoneViewController файлом .mm. Так что нет, это не решит.

вот еще немного информации: если я попытался вызвать метод / функцию экземпляра AQPlayer, будет отображаться ошибка «ошибка: не удается найти объявление интерфейса для 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, устранит ошибку, но мне нужно вызвать метод!

person Community    schedule 22.07.2009
comment
Вам следует отредактировать исходный вопрос, а не публиковать его в качестве ответа. Сказав это, как AQPlayer - это класс obj-c или C ++? Предварительное объявление, которое вы дали @class AQPlayer;, предназначено для Obj-C, но ваш вызов метода player->StartQueue(false); - это синтаксис C ++. Либо вы хотите class AQPlayer; для C ++, либо [player startQueue:NO]; для Obj-C. - person Daniel Dickison; 24.07.2009

У меня также была точно такая же проблема (я также пытался повторно использовать класс C ++ AQPlayer из демонстрации Apple «SpeakHere»).

Кажется, что компилятор сбивается с толку и пытается скомпилировать объектный c ++ как объектный c (отсюда и все ошибки). Мне удалось его скомпилировать, щелкнув правой кнопкой мыши файл m, который импортирует файл mm, и выбрав «getInfo», а затем изменив тип файла на «sourcecode.cpp.objcpp»

person atomoil    schedule 16.08.2009

Во-первых, вы должны сообщить компилятору, что файл имеет код C ++ (файл, содержащий также файл с кодом C ++!). Вы можете сделать это, переименовав его в расширение .mm (.h останется прежним). Второй способ - установить тип файла «sourcecode.cpp.objcpp», как сказал Atomoil.

Кроме того, если вам нужно предварительное объявление для класса C ++, вы используете «class AQPlayer;», а не «@class AQPlayer;». Если вы это сделаете, вы получите ошибку «не удается найти объявление интерфейса для XXX».

Я обычно включаю файлы C ++ в файл .h, устраняя необходимость в предварительном объявлении, хотя иногда вы не хотите этого делать.

person e75deaf2-fb2a-43e0-91ba-6caad0    schedule 17.12.2009