c++ - 从 C++ 代码调用 Objective C 函数

标签 c++ objective-c call

我用谷歌搜索了一下,找到了关于这个主题的一百万个结果。但是没有一页对我有帮助。我认为我有一个非常普遍的问题。我正在玩音频编程,尤其是使用音频队列。我的程序的目的与解释问题无关紧要。但简而言之:当我尝试从 C++ 代码调用 Objective-C 函数时出现错误。所以这是我的包含错误的代码: 录音机.h:

#import <Foundation/Foundation.h>


@interface AudioRecorder : NSObject {

}

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

@end

这是实现: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 函数呢?

最佳答案

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

关于c++ - 从 C++ 代码调用 Objective C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6958685/

相关文章:

c++ - 按位常量和指针 :

ios - Autolayout layoutIfNeeded 正在打破约束

ios - 设置后退按钮的名称和 View Controller 的标题

windows - cmd 环境变量行为不清楚

android - 从通话记录中获取 DISTINCT 最近联系的联系人

c++ - 具有作用域/代码块的互斥锁/锁

c++ - 有没有一种紧凑的方法可以使 std::optional<T>::value_or 处理 T 的成员变量

ios - 需要针对 Objective C 的 MVC 建议

c++ - 将 C++ DLL 加载到调用另一个 DLL 中的函数的 matlab

c++ - C++ std::container( vector )如何存储其内部结构(元素地址、按索引访问)?