首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS -在C代码中使用目标C变量

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

Stack Overflow用户
提问于 2012-10-30 16:32:18
回答 3查看 1.1K关注 0票数 1

我正在用iOS进行一些核心音频编程,我遇到了这样一种情况:我需要在一些C回调代码中使用我在Objective C中声明的变量。buffer变量必须能够被目标C和C语法访问,但是在C语法中,有一个错误说"Use of undeclared buffer“。

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

码头。

变量是buffer,在RIORecoerdingViewController.h中声明如下:

代码语言:javascript
复制
@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;
}

我希望在C回调函数中使用它

代码语言:javascript
复制
static OSStatus recordingCallback(void *inRefCon, 
                              AudioUnitRenderActionFlags *ioActionFlags, 
                              const AudioTimeStamp *inTimeStamp, 
                              UInt32 inBusNumber, 
                              UInt32 inNumberFrames, 
                              AudioBufferList *ioData) {

if (rio->recording)
{   
    TPCircularBufferProduceBytes(&buffer, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32)); //&buffer has an error "Use of undeclared identifier buffer"
}
return noErr;
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-31 04:26:41

这就是recordingCallback中的void * inRefCon参数的用途。当您设置RemoteIO回调时,它可能如下所示:

代码语言:javascript
复制
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc = &recordingCallback;
callbackInfo.inputProcRefCon = NULL;

AudioUnitSetProperty(rio,
                     kAudioOutputUnitProperty_SetInputCallback,
                     kAudioUnitScope_Global,
                     0,
                     &callbackInfo,
                     sizeof(callbackInfo));

您可以将inputProcRefCon用作在回调期间将成为inRefCon指针的任意指针。如果您只想访问一个变量,这很简单(只需传入该变量的地址)。例如,如果您需要的只是您的TPCircularBuffer:

代码语言:javascript
复制
callbackInfo.inputProcRefCon = &buffer;

然后,当调用recordingCallback时,您可以通过inRefCon参数访问缓冲区,如下所示:

代码语言:javascript
复制
TPCircularBuffer * bufferPtr = (TPCircularBuffer *)inRefCon;
TPCircularBufferProduceBytes(bufferPtr, abl.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt32));

如果您需要访问更多的变量(如recording布尔值),您可以创建一个结构并将其地址传递给它。

有传言说,你应该避免在AURenderCallbacks中调用Objective-C (由于消息开销),但我目前没有任何确凿的数据来支持这一点。您可以将self作为inputProcRefCon传递,但YMMV。

票数 1
EN

Stack Overflow用户

发布于 2012-10-30 17:05:49

您的buffer变量是一个具体RIORecoerdingViewController实例的实例变量。没有实例的情况下使用它是没有意义的(“缓冲区属于哪个对象?”)。

因此,如果你有一个实例,你可以像往常一样引用ivar (即,如果你想走C指针路线,就引用yourRecoerdingViewController->buffer )。

票数 2
EN

Stack Overflow用户

发布于 2012-10-31 05:54:25

Objective C是纯C语言的一个纯超集。它允许你将对象和实例变量指针复制到标准C语言全局变量、参数变量和结构(等等)中。

一种(被认为丑陋的)可能性是将缓冲区指针复制到C全局变量中(并确保手动将其设为空,或者在缓冲区释放时不使用它)。然后从任何地方访问它,任何C函数。

其他(可能更优雅的)可能性包括将缓冲区指针复制到传递给C回调的结构中,或者将指向对象本身的指针直接传递给或通过struct元素传递给C回调。然后,您可以在.m文件中的C函数中使用"->“语法来访问传递给标准C函数的任何对象的任何实例变量,例如音频单元回调。(C函数必须在.m文件中声明,以便可以导入对象定义的Objective C接口。)

还有一种可能,但不适合于音频回调,那就是让C函数(在.m文件中)向单例模型对象发送消息,以获取/设置模型对象状态(包括缓冲区指针)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13135240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档