如何在 C++ 中将非静态 class 方法作为回调函数传递?

How can I pass a non-static class method as a callback function in C++?

我正在使用的音频库将回调函数作为参数,它将音频写入缓冲区。

我正在编写一个名为 Instrument 的 class,其中我有一个方法 oscillator() 将正弦波写入缓冲区:

class Instrument {
private:
   int oscillator(int16_t* outputBuffer, ...){ // Writes a sine wave to outputBuffer
      ...
   }  
   RtAudio output;  // Object for outputting audio

public:
   void start() {
      output.openStream(settingsAndStuff, &oscillator);  // Error here
      ...
   }
}

编译器不喜欢这样,说oscillator()方法的类型与RtAudio.openStream()接受的类型不兼容。

如果 oscillator()static,它工作正常,大概是因为传递给方法的隐式 this 指针改变了它的类型。但是,我不能让它成为 static,因为我需要 oscillator() 才能访问 Instrument 字段(对于振幅和频率之类的东西)。

是否有任何需要最少包装器等的快速解决方案?

根据文档,

RtAudio::openStream() 将用户定义的参数作为回调的输入:

https://rtaudio.docsforge.com/master/api/RtAudio/openStream/

void openStream(..., RtAudioCallback callback, void *userData=NULL, ...)

public function for opening a stream with the specified parameters.

...

Parameters

...

callback - A client-defined function that will be invoked when input data is available and/or output data is needed.

userData - An optional pointer to data that can be accessed from within the callback function.

...

https://rtaudio.docsforge.com/master/api/#RtAudioCallback

typedef int(* RtAudioCallback)(..., void *userData)

RtAudio callback function prototype.

...

Parameters

userData - A pointer to optional data provided by the client when opening the stream (default = NULL).

...

userData 参数将允许您将 Instrument* 对象指针传递给 static 回调,例如:

class Instrument {
private:
    int static_oscillator(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData) {
        return static_cast<Instrument*>(userData)->oscillator(outputBuffer, inputBuffer, nFrames, streamTime, status);
    }

    int oscillator(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status) {
        // Writes a sine wave to outputBuffer
        return ...;
    }  

    RtAudio output;  // Object for outputting audio

public:
    void start() {
        output.openStream(..., &static_oscillator, this, ...);
        ...
    }
};