Доступ к свойству Obj-C из функции C ++ (iOS)

Я пишу приложение для iOS, которое выполняет некоторую обработку звука в AppDelegate с использованием Core Audio API. у меня есть @property в моем AppDelegate, который обновляется в ViewController, и это @property должен быть доступен в моей функции обратного вызова рендеринга, которая написана на C ++. К моему сожалению, я обнаружил, что вы не можете получить доступ к Obj-C @property в функции C ++, просто используя _propertyName как и в методе Obj-C, теперь мне интересно, как это сделать.

Вот мой @propertyв AppDelegate.h:

@property float centerFreq

Вот моя функция обратного вызова рендеринга в AppDelegate.m:

static OSStatus audioProcessingRenderCallback (
void *                           inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp *           inTimeStamp,
UInt32                           inBusNumber,
UInt32                           inNumberFrames,
AudioBufferList *                ioData
) {
//audio processing stuff that needs to access _centerFreq
}

Моей первой мыслью было просто сделать audioProcessingRenderCallback метод Objective C, но это вызывает ошибку, когда я пытаюсь установить это как функцию обратного вызова с этим кодом:

AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = audioProcessingRenderCallback;

Что было бы лучшим решением этой проблемы?

1

Решение

Один из способов, как я описал в своем комментарии к вашему посту, это изменить расширение вашего файла C ++. Сделайте расширение .mm (т.е. AudioProcessor.mm). Это включает Objective-C ++, и тогда вы можете просто передать свой объект и вызвать его из файла C ++. Это, наверное, проще всего.

Если вы не можете изменить расширение файла C ++, тогда вам нужно сделать функцию моста.

В вашем ViewController (файл .m) создайте функцию C следующим образом:

void updateCenterFreq( float value ) {
myViewControllerInstance.centerFreq = value;
}

Очевидно, вам нужно найти способ сделать экземпляр ViewController видимым для функции C. Одним из способов является назначение статического указателя в вашем файле .m. Полезно, только если у вас есть один экземпляр, и вы не беспокоитесь о потоках, но это может сработать для вас. Если у вас есть более одного экземпляра контроллера представления, вы должны найти способ найти экземпляр. Как это сделать, выходит за рамки моего ответа здесь. Я исправлю это, чтобы сказать, что если вы планируете вызывать updateCenterFreq () в неосновном потоке, то вам нужно использовать performSelectorOnMainThread чтобы попасть в основной поток, прежде чем установить centerFreq (я полагаю, так как это в контроллере представления вы планируете обновить пользовательский интерфейс, который должен быть сделано на основной ветке).

Теперь в вашем файле AudioProcessor.h (заголовок файла C ++) выполните:

extern "C" {
void updateCenterFreq( float value );
}

Затем вы можете вызвать updateCenterFreq (), когда вам нужно.

Опять же, это не касается безопасности потоков или того, как вы находите свой экземпляр, но это то, как вы можете это сделать.

0

Другие решения

Все, что вам нужно сделать, это передать ссылку на centerFreq к вашему методу:

static OSStatus audioProcessingRenderCallback (
float *                          centerFrequency,
void *                           inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp *           inTimeStamp,
UInt32                           inBusNumber,
UInt32                           inNumberFrames,
AudioBufferList *                ioData
) {
//audio processing stuff that needs to access _centerFreq
}

затем делайте то, что вы хотите сделать по этой ссылке, и обновления будут отражаться в вашей собственности.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector