0

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

CSerialSniffer.cpp|11|错误:无法从类型 'Nexus::TReceiveCallback (CSerialSniffer::)(Nexus::CData*, Nexus::IMetaData*)'}' 转换 'CSerialSniffer::AsyncRecieverReceived'| 键入'Nexus::typeAsyncReceiverCallback {aka Nexus::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);
}

它编译得很好。两者有什么区别?

4

2 回答 2

3

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

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

typeAsyncReceiverCallback l_pPointer = &CSerialSniffer::AsyncRecieverReceived;

C++11 的一个更好的选择是使用 astd::function<>代替:

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

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

CSerialSniffer snivver;

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

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

于 2012-08-23T13:55:30.953 回答
2

你的回调声明

typeAsyncReceiverCallback

是常规函数,但是

AsyncReceiverReceived

是一种方法(即它需要“this”指针,并且在 c++ 中无法以这种方式获取它)。

要么更改AsyncReceiverReceived为静态,要么使用观察者模式。

于 2012-08-23T13:55:32.247 回答