Objective c iOS-在C代码中使用目标C变量

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>

我正在用iOS做一些核心音频编程,现在我需要在一些C回调代码中使用我在Objective C中声明的变量。 目标C和C语法都必须可以访问缓冲区变量,但在C语法中有一个错误,即“使用未声明的标识符缓冲区”

我如何解决这个问题?提前谢谢

码头

变量是缓冲区,在riorecordingviewcontroller.h中声明如下:

@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文件中)消息一个单例模型对象来获取/设置模型对象状态(包括缓冲区指针)。

在应用程序的目标构建设置下检查“编译源代码为”如何?它有一些有趣的选择。不知道这会有什么帮助,无论如何谢谢!在应用程序的目标构建设置下检查“将源代码编译为”如何?它有一些有趣的选择。不确定这将如何实现