给出一个方法作为回调函数(gcc 4.7.1)



我试图将一个看似简单的回调方法指针设置到一个变量中,并得到以下错误:

CSerialSniffer.cpp|11|错误:无法转换来自类型的"CSerialSniffer::AsyncReciverReceived"'Nexus::TReceiveCallback(CSerialSniffer::)(Nexus:;CData*,Nexus::IMetaData*)"}"|以键入"Nexus:"typeAsyncReceiverCallback{akaNexus::TReceiveCallback()(Nexus:CData,Nexus:IMetaData*)}'|

下面是set语句:

typeAsyncReceiverCallback l_pPointer = AsyncRecieverReceived;

我定义了以下内容:

typedef TReceiveCallback (*typeAsyncReceiverCallback)(CData *a_pData, IMetaData *a_pMetaData);
class CSerialSniffer
{
...
public:
    Nexus::TReceiveCallback AsyncRecieverReceived(Nexus::CData *a_pData, Nexus::IMetaData *a_pMetaData);
...
}

我已经做了好几个小时了,有什么想法吗?

回答:我在这里有相同的回调机制:

typedef void (*EnqueueCallback)( PData *pd );
class SomeClass
{
...
public:
   void enqueue( PData *pd );
...
};

class CSerialSniffer
{
...
public:
    void set_enqueue_callback(EnqueueCallback a_pEnqueueCallback );
...
}

SomeClass::SomeFunction(){
 this->serialSniffer->set_enqueue_callback(this->enqueue);
}

而且它编译得很好。两者之间有什么区别?

您的CSerialSniffer::AsyncRecieverReceived是一个成员函数。它不能在没有对象的情况下使用,所以要么将其作为一个自由函数(类外),要么作为一个静态函数:

class CSerialSniffer
{
...
public:
    static Nexus::TReceiveCallback AsyncRecieverReceived(
         Nexus::CData *a_pData, 
         Nexus::IMetaData *a_pMetaData);
...
};
typeAsyncReceiverCallback l_pPointer = &CSerialSniffer::AsyncRecieverReceived;

C++11的一个更好的替代方案是使用std::function<>

typedef std::function<TReceiveCallback(CData*,IMetaData*)> 
        typeAsyncReceiverCallback;

现在,您可以通过绑定一个对象作为成员函数的第一个参数来创建一个自由函数:

CSerialSniffer snivver;
auto callback = std::bind( 
     std::mem_fun( &CSerialSniffer::AsyncRecieverReceived ),
     &snivver );

这些好东西在<functional>标头中。

您的回调声明

typeAsyncReceiverCallback

是常规函数,但

AsyncReceiverReceived

是一个方法(即它需要"this"指针,并且在c++中不可能以这种方式获得它)。

AsyncReceiverReceived更改为static或使用observer模式。

最新更新