C++ 从C++;代码
我在谷歌上搜索了一下,找到了一百万个关于这个主题的结果。但是没有一页对我有帮助。我想我有一个非常普遍的问题。我正在玩音频编程,尤其是处理音频队列。我的程序的目的与解释问题无关。但简单来说,当我尝试从C++代码调用Objto-C函数时,会出错。下面是我的代码,其中包含错误: 录音机.h:C++ 从C++;代码,c++,objective-c,call,C++,Objective C,Call,我在谷歌上搜索了一下,找到了一百万个关于这个主题的结果。但是没有一页对我有帮助。我想我有一个非常普遍的问题。我正在玩音频编程,尤其是处理音频队列。我的程序的目的与解释问题无关。但简单来说,当我尝试从C++代码调用Objto-C函数时,会出错。下面是我的代码,其中包含错误: 录音机.h: #import <Foundation/Foundation.h> @interface AudioRecorder : NSObject { } -(void)setup; -(void)s
#import <Foundation/Foundation.h>
@interface AudioRecorder : NSObject {
}
-(void)setup;
-(void)startRecording;
-(void)endRecording;
-(void)playAlarmSound;
@end
#导入
@接口录音机:NSObject{
}
-(无效)设置;
-(无效)开始记录;
-(无效)终止记录;
-(无效)播放警报声;
@结束
这是实现:AudioRecorder.mm:
#import "AudioRecorder.h"
#include <AudioToolbox/AudioToolbox.h>
#include <iostream>
using namespace std;
@implementation AudioRecorder
static const int kNumberBuffers = 3;
...
static void HandleInputBuffer (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc ) {
AQRecorderState *pAqData = (AQRecorderState *) aqData;
if (inNumPackets == 0 &&
pAqData->mDataFormat.mBytesPerPacket != 0)
inNumPackets =
inBuffer->mAudioDataByteSize / pAqData->mDataFormat.mBytesPerPacket;
UInt32 size;
AudioQueueGetPropertySize ( inAQ, kAudioQueueProperty_CurrentLevelMeter, &size );
char* levelMeterData = new char[size];
AudioQueueGetProperty ( inAQ, kAudioQueueProperty_CurrentLevelMeter, levelMeterData, &size );
AudioQueueLevelMeterState* meterState = reinterpret_cast<AudioQueueLevelMeterState*>(levelMeterData);
cout << "mAveragePower = " << meterState->mAveragePower << endl;
cout << "mPeakPower = " << meterState->mPeakPower << endl;
delete levelMeterData;
[self playAlarmSound]; //<--- here I get the error: Use of undeclared identifier 'self'
if (pAqData->mIsRunning == 0)
return;
AudioQueueEnqueueBuffer ( pAqData->mQueue, inBuffer, 0, NULL );
}
...
-(void)playAlarmSound {
NSLog(@"Alarmsound....");
}
#导入“AudioRecorder.h”
#包括
#包括
使用名称空间std;
@录音机的实现
静态常数int kNumberBuffers=3;
...
静态void HandleInputBuffer(void*aqData,
音频队列参考inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp*inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription*inPacketDesc){
AQRecorderState*pAqData=(AQRecorderState*)aqData;
如果(inNumPackets==0&&
pAqData->mDataFormat.mBytesPerPacket!=0)
inNumPackets=
在buffer->mAudioDataByteSize/pAqData->mDataFormat.mBytesPerPacket;
UInt32尺寸;
AudioQueueGetPropertySize(inAQ、kAudioQueueProperty_CurrentLevelMeter和size);
char*levelMeterData=新字符[大小];
AudioQueueGetProperty(inAQ、kAudioQueueProperty_CurrentLevelMeter、levelMeterData和size);
AudioQueueLevelMeterState*meterState=重新解释强制转换(levelMeterData);
cout这确实是一个常见问题。self
在这里不起作用,因为这不是AudioRecorder
类的方法,也不是因为它是Objective-C代码。您在Objective-C++文件中,所以所有有效的Objective-C代码都可以工作。[anAudioRecorder playAlarmSound]
如果您对音频录像机有一个很好的参考,它将很好地工作
那么,如果我们不能访问self
,我们如何获得引用呢?通常的方法是使用此函数的void*aqData
参数作为指向AudioRecorder
对象的指针。当您注册此回调时,您告诉它void*
参数是什么,在本例中是指向AQRe的指针corderState
对象或结构,您似乎无论如何都不会使用它。相反,您可以在注册时使用指向self
的指针,以便在此处使用该对象
另一种选择是使用共享的录音机
对象,在这种情况下,您可以调用类似[AudioRecorder sharedInstance]
(类,而不是实例,方法)获取所需的AudioRecorder
对象。因为这里的另一个答案详细介绍了第一种方法,下面介绍如何使用共享实例选项:将AudioRecorder
的静态实例和类方法sharedInstance
添加到AudioRecorder
对象中,如下所示:
static AudioRecorder* sharedMyInstance = nil;
+ (id) sharedInstance {
@synchronized(self) {
if( sharedMyInstance == nil )
sharedMyInstance = [[super allocWithZone:NULL] init];
}
return sharedMyInstance;
} // end sharedInstance()
然后,当您想从回调中使用录音机时,您可以使用[AudioRecorder sharedInstance]获取共享实例
。如果只有一个录音机,这是一个非常有用的范例,它消除了大量的引用传递。self
仅存在于Objective-C方法中,这是一个C风格的函数。设置回调时,需要将self
从Objective-C方法传递到inUserData,然后将其转换回正确的类型
//This is an example for using AudioQueueNewInput
//Call this in an Objective-C method passing self to inUserData
AudioQueueNewInput (
const AudioStreamBasicDescription *inFormat,
AudioQueueInputCallback inCallbackProc,
// this is where you will pass (void*)self
void *inUserData,
CFRunLoopRef inCallbackRunLoop,
CFStringRef inCallbackRunLoopMode,
UInt32 inFlags,
AudioQueueRef *outAQ
);
以及您最初的实现
static void HandleInputBuffer (void *aqData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc )
{
AudioRecorder *ar_instance = (AudioRecorder*)aqData;
...
[ar_instance playAlarmSound];
...
}
是的,但我认为“self”缺失的根本原因是因为它不是类的方法,不是因为它是C风格的函数。任何Objective-C对象都可以在这个函数中使用——只是“self”只在类的方法中可用。我相信这就是我所说的“self只存在于Objective-C方法中,这是一个C风格的函数”最初有一个拼写错误,上面写着一个,但应该传达相同的信息。