Search code examples
c++classcallbackfriend-function

frame grabbing with a callback function in c++. how does it communicate with a class?


I recently bought a GigE camera tha came bundles with its SDK. One of the examples explains how to grab frames from the camera through a callback function. It works in the following way:

void OnImageGrabbed(Image* pImage, const void* pCallbackData)
{
    printf( "Grabbed image %d\n", imageCnt++ );
    return;
}

//...

int main(int argc, char** argv)
{
    camera.StartCapture(OnImageGrabbed);
}

the above is based on a simple cpp program (no objects involved).

Now I am trying to incorporate the functionality in my object oriented application (written in openFrameworks ). I am really fuzzy as to how to do that and I haven't been able to find close enough example to follow on the internet.

basically what I do in my header file:

class ofApp : public ofBaseApp{

    public:
        void setup();
        void update();
        void draw();

        friend void OnImageGrabbed(Image* pImage, const void* pCallbackData);

        bool bNewFrameArrived;
};

then in my implementation (.cpp) file

void ofApp::setup()
{
    bNewFrame = false ;
    cam.StartCapture(OnImageGrabbed);
}

void OnImageGrabbed(Image* pImage, const void* pCallbackData)
{
    bNewFrame = false ;
    cout<< "Grabbed image" << endl;

    bNewFrame = true ;
}

void ofApp::update(){
    //somehow grab the pImage. but how???

    if ( bNewFrame ) 
        //do stuff
}

having this as a friend class is fine, but how can I access the instantiation of the ofApp class (namely the bNewFrame variable)? Also how can I access pImage afterwards from my update() member function?

Thank you for your help!


Solution

  • There are couple of ways, depending on can you use member functions or even lambdas as a callback. If it is a C-style function pointer, then options are slightly limited.

    Firstly, you could add a static std::deque or std::vector to file scope, where callback pushes the image pointers. After that, process whatever Image pointers the queue/vector holds. See the following.

    static std::vector<Image*> s_imageQueue;
    ....
    
    void onImageGrabbed(Image* image, const void* callbackData)
    {
        s_imageQueue.push_back(image);
    }
    ...
    
    void ofApp::update()
    {
        ...
        for (auto image : s_imageQueue)
        {
            // process image
        }
        s_imageQueue.clear();
        ...
    }
    

    If camera.StartCapture() accepts std::function<void(Image*,const void*)>, you could just do something like the following.

    void ofApp::setup()
    {
        camera.StartCamera( [] (Image* image, const void* data) {
            // process image here
        });
    }