我在使用 C 音频库时遇到了问题(使用 ASIO SDK 构建的 PortAudio,但这与这个问题并不真正相关;技术细节只会阻碍我提出问题) .
简单地说,该库中的某个 C 函数要求我为其提供一个回调函数,该回调函数返回特定值并接受特定参数;为了清楚起见,我们假设回调应该如下所示:
int callback(int arg)
对库函数的调用如下所示:
theCLibraryFuntion(foo, bar, callback);
像这样使用库(即以过程 C 风格的方式)工作得很好,但我想将与我相关的库功能包装在结构良好的 C++ 类中。我需要该库的项目是迄今为止我从事过的最大的项目,因此面向对象设计对我来说是必须的。 我想在 C++ 中创建一个抽象类,为派生类提供要实现的纯虚函数,然后让了解该库的类将该实现用于回调。 换句话说,我需要实际的多态性,而不是令人讨厌的函数指针。
到目前为止我还无法编写这样的类。编译器不允许我将任何类的非静态成员函数作为回调传递给 C 库函数。我明白为什么,但我想知道一些解决方法。只要该解决方法(如果存在)为我提供了前端类的多态行为,我不在乎后端代码变得多么邪恶。如果不存在这样的解决方法,那就这样吧。我非常了解 C 在后台如何工作,但我对 C++ 中 OO 功能的技术细节知之甚少,所以我假设有一种方法。
提前致谢!
注意:会增加大量开销的解决方法对我来说可能毫无值(value)。我被迫使用这个 C portaudio 库,因为它是唯一一个能够为我的项目所需的音频流提供极低延迟的 API,因此大幅增加开销并不是一个真正的选择。
最佳答案
您的代码过于简单。在现实世界中,“库函数”和回调都会有一个 void*
“用户数据”参数。您可以将指向类实例的指针传递到“库函数”的“用户数据”中,它将被转发到回调中,您可以在其中使用该指针访问该对象。
class CallbackImplBase {
public:
virtual void CallbackImpl() = 0;
static void CallbackToPass( void* userData )
{
static_cast<CallbackImplBase*>(userData)->CallbackImpl();
}
};
class ActualCallbackImpl : public CallbackImplBase {
void CallbackImpl() { //implemented here }
};
ActualCallbackImpl callback;
callLibraryFunction( params,
&CallbackImplBase::CallbackToPass, static_cast<CallbackImplBase*>( &callback ) );
注意“库函数”调用的最后一个参数附近的static_cast
。除非您有多重继承,否则您将不需要它,无论如何它仍然存在。
关于c++ - 在 C++ 抽象类中将回调(对于 C 库)实现为纯虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21480582/