我正在编写一个iOS应用程序,该应用程序使用Core Audio API在AppDelegate中进行了一些音频处理。@property
我的AppDelegate中有一个在ViewController中更新的,并且@property
需要在使用C ++编写的渲染回调函数中进行访问。我很生气地发现,不能像在Obj-C方法中那样@property
简单地使用_propertyName
,就无法在C ++函数中访问Obj-C,所以现在我想知道如何去做。
这是@property
AppDelegate.h中的my :
@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;
什么是解决此问题的最佳解决方案?
正如我在对您的帖子的评论中所述,一种方法是更改C ++文件的扩展名。扩展名为.mm(即AudioProcessor.mm)。这将启用Objective-C ++,然后您就可以传递对象并从C ++文件对其进行调用。这可能是最简单的。
如果您不能更改C ++文件的扩展名,则需要创建一个桥接函数。
在ViewController(.m文件)中,使C函数如下所示:
void updateCenterFreq( float value ) {
myViewControllerInstance.centerFreq = value;
}
显然,您必须找到一种使ViewController实例对C函数可见的方法。一种方法是在.m文件中分配静态指针。仅在只有一个实例且不担心线程的情况下才有用,但这可能对您有用。如果您有多个视图控制器实例,则必须找到一种定位实例的方法。如何做到这一点超出了我在这里的回答范围。我将对此进行修正,但如果您打算在非主线程上调用updateCenterFreq(),那么您需要先使用performSelectorOnMainThread
来进入主线程,然后再设置centerFreq(我假设是因为它在视图控制器中,正在计划更新UI,必须在主线程上完成)。
现在,在您的AudioProcessor.h文件(C ++文件的标头)中执行以下操作:
extern "C" {
void updateCenterFreq( float value );
}
然后,您可以在需要时调用updateCenterFreq()。
同样,这不考虑线程安全或实例的定位方式,但这是您可以执行的方式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句