从C ++代码调用Objective C函数 [英] Calling a Objective C function from C++ Code

查看:169
本文介绍了从C ++代码调用Objective C函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索了一下,我发现这个主题有一百万个结果。但没有一页能帮助我。我认为我有一个非常普遍的问题。我正在玩的音频编程,特别是使用音频队列。我的程序的目的无关紧要解释这个问题。但简而言之:当我尝试从c ++代码调用一个objective-c函数时,我得到一个错误。所以这里是我的代码包含错误:
AudioRecorder.h:

I googled around and I find a million results to this subject. But none of the pages helps me. I think that I have a very common problem. I'm playing around with audio programming especially working with audio queues. The purpose of my program does not matter for explaining the problem. But in a nutshell: I get an error when I try to call an objective-c function from c++ code. So here is my code that contains the error: AudioRecorder.h:

#import <Foundation/Foundation.h>


@interface AudioRecorder : NSObject {

}

-(void)setup;
-(void)startRecording;
-(void)endRecording;
-(void)playAlarmSound;

@end

这是实现:AudioRecorder.mm: / p>

And this is the implementation: 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....");
}



当我省略[self playAlarmSound]然后一切工作正常。那么如何从我的C ++代码调用这个Objective-C函数?

When I omit "[self playAlarmSound];" then everything works fine. So how do I call this Objective-C function from my C++ code?

推荐答案

self 只存在于Objective-C方法中,它是一个C风格函数。当您设置回调时,您需要将 self 从Objective-C方法传递给inUserData,然后将其转换回正确的类型。

self only exists in Objective-C methods and that is a C style function. You need to pass self from an Objective-C method to the inUserData when you set up the callback, then cast it back to the correct type.

//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];
    ...
}

这篇关于从C ++代码调用Objective C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆