c++ - 在 C++ 抽象类中将回调(对于 C 库)实现为纯虚函数

标签 c++ c callback polymorphism

我在使用 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/

相关文章:

带线程的 C++ 网络类

c++ - 具有 PPL 和并行内存分配的线程 ID

c - 指针被莫名其妙地修改

javascript - 如何在回调中访问正确的“this”?

c - 如何传递 extern(C) 函数文字?

c# - 在回调中返回

c++ - 苹果机 : I get SIGABRT but the call stack is useless

c++ - 将所有项目头文件放入一个文件 HEADERS.h 中是个好主意吗?

c - 必须在多大程度上使用原子类型来保证跨线程可见性?

c++ - 重叠缓冲区的 memcpy