我的C ++技能很轻但我设法完成任务 - 直到我碰壁。目前的墙:
我正在使用CoreAudio来做一些Midi播放的东西。我有很多工作,但我坚持一个简单的事情。 (我不知道正确的C ++术语,所以请耐心等待......)。
我在CoreAudio中使用渲染回调函数来指示何时由AU渲染midi音符事件。如果我将它定义为非类函数并坚持使用main.cpp(或testApp.cpp),它就可以了 - 我得到了事件。问题是我需要能够让testApp的实例获得这些事件。
那么..有没有办法从main.cpp获取testApp的实例,所以我可以调用我需要的testApp方法?
OR是否有一些C ++ voodoo有一个非类函数驻留在类中调用实例的方法?例如,如果下面的函数在我的类中,它如何调用类的实例上的方法...
OSStatus renderCallback(void *inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
someClassMethod(); // doesn't work
this.someClassMethod(); // doesn't work
self.someClassMethod(); // doesn't work
}
我不确定,但我认为CoreAudio的东西不会将实例方法作为回调 - 至少这是我从错误消息收集的内容(下面)。无论如何我做得很好。
感谢任何提示!
错误:OSStatus类型的参数(testApp ::)(void *, AudioUnitRenderActionFlags *,const AudioTimeStamp *,UInt32,UInt32, AudioBufferList *)'与'OSStatus()不匹配(void , AudioUnitRenderActionFlags *,const AudioTimeStamp *,UInt32,UInt32, AudioBufferList *)
答案 0 :(得分:2)
您不需要乱用静态实例来执行此操作。添加渲染回调时,将C ++对象作为refcon传递,然后将refcon转换为回调中的对象:
// The actual callback is defined as a static function
static OSStatus
myAURenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
MyClass *object = static_cast<MyClass *>(inRefCon);
return object->Render(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}
// When adding the render callback pass this as the context
AURenderCallbackStruct cbs = { myAURenderCallback, this };
OSStatus result = AUGraphSetNodeInputCallback(graph, node, 0, &cbs);
// The callback will look like
OSStatus MyClass::Render(AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
// Do something
}
答案 1 :(得分:0)
sbooth的answer是 anwser,因为api设计师为您提供了一个很好的技巧。但是,如果您将回调传递给设计较差的c库,则下面的答案可能有所帮助。
你需要从指向成员的函数到指向函数的指针。
你可以:
1。使someMethod()静态并保留testApp的静态实例(如果需要旋转实例数据) 2. 全局存储testApp指针并从您正在使用的全局函数中使用它
以下是方法1 的示例,我建议
class Test
{
public:
Test();
void InstanceCallback();
static void StaticCallbackMethod();
private:
static Test* instance;
};
// Normally in cpp
Test* Test::instance = 0;
Test::Test()
{
instance = this;
}
void Test::InstanceCallback()
{
// do stuff;
}
void Test::StaticCallbackMethod()
{
if (instance)
{
instance->InstanceCallback();
}
}
int main()
{
Test* t = new Test();
void (*mf)();
mf = &Test::StaticCallbackMethod;
mf();
return 0;
}
答案 2 :(得分:0)
你是正确的,你不能在这里使用指向实例方法的指针(由于回调实际上没有通过对象调用,所以无法提供隐式的'this'指向成员函数的指针)。
你可以使用静态成员函数(然后你需要一些方法来提供指向testApp实例的指针(全局变量,静态实例等))。
答案 3 :(得分:0)
如果你可以安装boost,boost :: bind可以为你做这个。