Objective c iOS-在C代码中使用目标C变量
我正在用iOS做一些核心音频编程,现在我需要在一些C回调代码中使用我在Objective C中声明的变量。 目标C和C语法都必须可以访问缓冲区变量,但在C语法中有一个错误,即“使用未声明的标识符缓冲区” 我如何解决这个问题?提前谢谢 码头 变量是缓冲区,在riorecordingviewcontroller.h中声明如下:Objective c iOS-在C代码中使用目标C变量,objective-c,ios,c,core-audio,Objective C,Ios,C,Core Audio,我正在用iOS做一些核心音频编程,现在我需要在一些C回调代码中使用我在Objective C中声明的变量。 目标C和C语法都必须可以访问缓冲区变量,但在C语法中有一个错误,即“使用未声明的标识符缓冲区” 我如何解决这个问题?提前谢谢 码头 变量是缓冲区,在riorecordingviewcontroller.h中声明如下: @interface RIORecoerdingViewController : UIViewController <AVAudioSessionDelegate>
@interface RIORecoerdingViewController : UIViewController <AVAudioSessionDelegate> {
OSStatus status;
AudioComponentInstance audioUnit;
AudioStreamBasicDescription audioFormat;
RIO rio;
IBOutlet UIButton *button;
BOOL isPlaying;
Float64 graphSampleRate;
NSString *destinationFilePath;
CFURLRef destinationURL;
ExtAudioFileRef outExtAudioFile;
// New
AUGraph theGraph;
TPCircularBuffer buffer;
}
您的
buffer
变量是具体riorecordingviewcontroller
实例的实例变量。在没有实例的情况下使用它是没有意义的(“缓冲区属于哪个对象?”)
因此,如果您有一个实例,您可以像往常一样引用ivar(即
YourRecordingViewController->buffer
,如果您想走C指针路线)。您的buffer
变量是一个具体RioRecordingViewController
实例的实例变量。在没有实例的情况下使用它是没有意义的(“缓冲区属于哪个对象?”)
因此,如果您有一个实例,您可以像往常一样引用ivar(即,
YourRecordingViewController->buffer
,如果您想使用C指针路径)。这就是recordingCallback
中的void*inRefCon
参数的作用。当您设置RemoteIO回调时,它可能看起来像这样:
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc = &recordingCallback;
callbackInfo.inputProcRefCon = NULL;
AudioUnitSetProperty(rio,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));
您可以将inputProcRefCon
用作任意指针,在回调期间,该指针将成为inRefCon
指针。如果只想访问一个变量,那么很容易(只需传入该变量的地址)。例如,如果您只需要TPCircularBuffer:
callbackInfo.inputProcRefCon = &buffer;
然后,当调用recordingCallback
时,您可以通过inRefCon
参数访问缓冲区,如下所示:
TPCircularBuffer * bufferPtr = (TPCircularBuffer *)inRefCon;
TPCircularBufferProduceBytes(bufferPtr, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32));
如果您需要访问更多变量(比如记录布尔值),您可以创建一个结构并将其地址传入
人们普遍认为,在您的AURenderCallbacks中应该避免使用Objective-C调用(由于消息传递开销),但我目前没有任何硬数据来支持这一点。您可以将self
作为inputProcRefCon
传递,但这是recordingCallback
中的void*inRefCon
参数的作用。当您设置RemoteIO回调时,它可能看起来像这样:
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc = &recordingCallback;
callbackInfo.inputProcRefCon = NULL;
AudioUnitSetProperty(rio,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));
您可以将inputProcRefCon
用作任意指针,在回调期间,该指针将成为inRefCon
指针。如果只想访问一个变量,那么很容易(只需传入该变量的地址)。例如,如果您只需要TPCircularBuffer:
callbackInfo.inputProcRefCon = &buffer;
然后,当调用recordingCallback
时,您可以通过inRefCon
参数访问缓冲区,如下所示:
TPCircularBuffer * bufferPtr = (TPCircularBuffer *)inRefCon;
TPCircularBufferProduceBytes(bufferPtr, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32));
如果您需要访问更多变量(比如记录布尔值),您可以创建一个结构并将其地址传入
人们普遍认为,在您的AURenderCallbacks中应该避免使用Objective-C调用(由于消息传递开销),但我目前没有任何硬数据来支持这一点。您可以将self
作为inputProcRefCon
传递,但是YMMV.Objective C是纯C的超集。它允许您将对象和实例变量指针复制到标准C全局变量、参数变量和结构(等等)中
一种(被认为是丑陋的)可能性是将缓冲区指针复制到一个C全局变量中(并确保手动将其设为null,或者在释放缓冲区时不使用它)。然后从任何地方访问它,任何C函数
其他(可能更优雅)的可能性包括将缓冲区指针复制到传递给C回调的结构中,或将指向对象本身的指针直接传递给C回调,或通过结构元素传递给C回调。然后,您可以使用.m文件中C函数的“->”语法来访问传递给标准C函数的任何对象的任何实例变量,例如音频单元回调。(必须在.m文件中声明C函数,以便导入对象定义的Objective C接口。)
还有另一种可能性,但不适合音频回调,就是让C函数(在.m文件中)消息一个单例模型对象来获取/设置模型对象状态(包括缓冲区指针)。Objective C是纯C的超集。它允许您将对象和实例变量指针复制到标准C全局变量中,参数变量和结构(等)
一种(被认为是丑陋的)可能性是将缓冲区指针复制到一个C全局变量中(并确保手动将其设为null,或者在释放缓冲区时不使用它)。然后从任何地方访问它,任何C函数
其他(可能更优雅)的可能性包括将缓冲区指针复制到传递给C回调的结构中,或将指向对象本身的指针直接传递给C回调,或通过结构元素传递给C回调。然后,您可以使用.m文件中C函数的“->”语法来访问传递给标准C函数的任何对象的任何实例变量,例如音频单元回调。(必须在.m文件中声明C函数,以便导入对象定义的Objective C接口。)
还有一种可能性,但不适合音频回调,就是让C函数(在.m文件中)消息一个单例模型对象来获取/设置模型对象状态(包括缓冲区指针)。在应用程序的目标构建设置下检查“编译源代码为”如何?它有一些有趣的选择。不知道这会有什么帮助,无论如何谢谢!在应用程序的目标构建设置下检查“将源代码编译为”如何?它有一些有趣的选择。不确定这将如何实现