Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

How to pass user data to callback function specified in imgSessionAcquire

I'm trying to acquire images through NI-IMAQ, and am using the low-level interface. Specifically, I would like to initiate a "grab" operation and whenever the acquisition is complete,i.e. the buffer is full/done, the callback function would execute. This callback function would then be able to process the acquired image.

I see from LLgrab.c and the online help that I can configure such a callback function through "imgSessionAcquire". More notably, the function declaration for the fall back (as specified in niimq.h) is:

typedef  uInt32   (__cdecl * CALL_BACK_PTR)(SESSION_ID boardid, IMG_ERR err, uInt32 signal, void* data);

[for the non-C/C++ programmers out there, it specifies a function returning a uInt32 (unsigned integer, 32-bit) and takes as arguments a SESSION_ID (boardid), an IMG_ERR (err) error code, and finally, a pointer to undefined data (void *data)].

It is the last argument that I have the most interest. What exactly is getting passed as the (void *)data, and can I set this value? I assume, like many traditional C API's, this parameter was implemented to permit user to pass user-specific data. This is clearly the intention as seen in the documentation which describes the function prototype as:

uInt32(*function)(SESSION_ID sid, IMG_ERR err, uInt32 signal, void* userdata)

How do I go about specifying the value to use for userdata? I would have thought in imgSessionAcquire() I can pass in an additional argument, specifically the value of the (void *)data, but I checked the function prototype in <niimaq.h> and I don't see any additional parameters there.

For more background, I'm using C++ and object-oriented programming, so I need to pass the "this" pointer in the user data portion in order to access the instance. Thanks.


--
[System info: NI-1429e running in 'Base' CL-mode plugged into an x4 PCI-e slot on a Dell PowerEdge 1800, dual 3.2Ghz Xenon, 6GB RAM, Windows 2003 Server SP1, LV8.0/7.1, IMAQ v3.5, Dell CERC SATA RAID controller card with 4x250GB Seagate HDD, one Seagate 250GB HDD connected to system's primary SATA port for OS.]
0 Kudos
Message 1 of 3
(5,224 Views)

Hi Harold,

First, the bad news... The callback on imgSessionAcquire() does not let you pass user data to the callback. 

Now the good news.. You can get the same behavior with imgSessionWaitSignalAsync().  Here's some example code.

//--------------------------------------

#include "niimaq.h"

class Foo {
    public:
        uInt32 DoSomething(SESSION_ID id, IMG_ERR err, uInt32 signal);
};


uInt32 __cdecl Callback(SESSION_ID id, IMG_ERR err, uInt32 signal, void* data) {
    Foo* myObj = reinterpret_cast<Foo*>(data);
    return myObj->DoSomething(id, err, signal);
}


main() {
    Foo* myObj = new Foo;
    SESSION_ID id;

    //... Setup grab, do other stuff, then
    imgSessionAcquire(id, true, NULL);

    //If you want to get a callback after each image
    imgSessionWaitSignalAsync(id, IMG_BUF_COMPLETE, IMG_SIGNAL_STATE_RISING, Callback, static_cast<void*>(myObj));

    //If you want to get a callback when the acquisition is complete
    imgSessionWaitSignalAsync(id, IMG_AQ_DONE, IMG_SIGNAL_STATE_HIGH, Callback, static_cast<void*>(myObj));

    //... Eventually clean up, etc.

    return 0;
}

//----------------

Good luck

 

 

Message 2 of 3
(5,208 Views)
Ah, thank you very much! I knew there must be a reason why they left that extra (void *) in there.
I just didn't look hard enough. Thanks again!
--
[System info: NI-1429e running in 'Base' CL-mode plugged into an x4 PCI-e slot on a Dell PowerEdge 1800, dual 3.2Ghz Xenon, 6GB RAM, Windows 2003 Server SP1, LV8.0/7.1, IMAQ v3.5, Dell CERC SATA RAID controller card with 4x250GB Seagate HDD, one Seagate 250GB HDD connected to system's primary SATA port for OS.]
0 Kudos
Message 3 of 3
(5,201 Views)