c++kinectlibfreenect2

How to make listener accessible for other functions in C++?


I want to make the following listener accessible for my getFrames() function. How can I do this? I tried this by adding the listener to my private fields, but I still get the following error on listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth | libfreenect2::Frame::Ir);:

no match for call to ‘(libfreenect2::SyncMultiFrameListener) (int)

Please take a look at the example application code

Source file:

int KinectConnector::connect() {
    //! [listeners]
    listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth | libfreenect2::Frame::Ir);

    dev->setColorFrameListener(&listener);
    dev->setIrAndDepthFrameListener(&listener);     
}

void KinectConnector::getFrames() {
    while (!protonect_shutdown) {
        listener.waitForNewFrame(frames);
    }
}

Header file:

class KinectConnector {
public:
    KinectConnector();
    virtual ~KinectConnector();
    int connect();
    void getFrames();
private:
    libfreenect2::SyncMultiFrameListener listener
    libfreenect2::FrameMap frames;
};

Example application from github:

/// [listeners]
  int types = 0;
  if (enable_rgb)
    types |= libfreenect2::Frame::Color;
  if (enable_depth)
    types |= libfreenect2::Frame::Ir | libfreenect2::Frame::Depth;
  libfreenect2::SyncMultiFrameListener listener(types);
  libfreenect2::FrameMap frames;

  dev->setColorFrameListener(&listener);
  dev->setIrAndDepthFrameListener(&listener);
/// [listeners]

Solution

  • From observation:

    listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth | libfreenect2::Frame::Ir);
    

    Will cause a compilation error. As you are attempting to call the ()(int) operator of listener with the flags and apparently the listener object has no ()(int) operator defined for it.

    As such the error message:

    no match for call to ‘(libfreenect2::SyncMultiFrameListener) (int)

    What you are doing here is attempting to construct listener with those flags. You can only do that expression in the constructor of the class unless libfreenect2::SyncMultiFrameListener has an operator() for that purpose.

    Just browsing the source code of libfreenect2::SyncMultiFrameListener, there is no default constructor available. Which means you need to supply the flags upon initialization or construction.

    Difference

    Note the difference between these 2 codes:

    // listener declared with types as shown in Github Example
    // calls the libfreenect2::SyncMultiFrameListener(int) constructor
    libfreenect2::SyncMultiFrameListener listener(types);
    
    // Essentially what your code does is this, 
    // when you declare in the header file without initializing in the constructor
    // calls the libfreenect2::SyncMultiFrameListener() constructor which don't exists
    libfreenect2::SyncMultiFrameListener listener2();
    

    You can read more on here under Constructor

    There are several ways you can resolve this:

    Initializing in expression

    Make the following changes:

    Header:

    class KinnectConnector
    {
        ...
    private:
        libfreenect2::SyncMultiFrameListener* listener;
        ...
    };
    

    Source:

    int KinectConnector::connect() {
        listener = new libfreenect2::SyncMultiFrameListener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth | libfreenect2::Frame::Ir);
        ...
    }
    

    *Remember to delete after use with delete listener; in the destructor or somewhere else.

    Initializing in constructor

    Do the following to initialize listener when KinnectConnector is constructed

    KinectConnector::KinectConnector()
    : listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth | libfreenect2::Frame::Ir)
    {
        ...
    }
    

    For safety, it might be better to go with the constructor example but that depends on your use case.