Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Using DAQmxRegisterSignalEvent CallBack in C++

I have successfully used and modified the ReadDigChan-ChangeDetectionEvent ASCII-C sample program. Only, things stopped working as soon as I transitioned from sample practice code to the c++ project where I wanted to put the demonstrated functions to use.

 

 

Below is the abbreviated code:

//-------------------My_NI_Functions.h--------------

class My_NI

{

public:

    My_NI( void ); //constructor

 

    //Assorted Variables

 

    int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskListen, int32 signalID, void *callbackData);

 

    //Other assorted functions

};

 

//-----------------My_NI_Functions.cpp-----------

#include "My_NI_Functions.h"

//other assorted includes

 

My_NI::My_NI( void ) {

    //One-time initialization stuff

    DAQmxErrChk (DAQmxCreateTask("",&taskListen));
    DAQmxErrChk (DAQmxCreateDIChan(taskListen,"Dev1/port0/line4","",DAQmx_Val_ChanPerLine));
    DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskListen,"Dev1/port0/line4",NULL,DAQmx_Val_ContSamps,1));
    DAQmxErrChk (DAQmxRegisterSignalEvent(taskListen,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
    DAQmxErrChk (DAQmxGetTaskNumChans(taskListen,&numLines));

}

 

int32 CVICALLBACK CNIComm:: ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData) {
     //assorted logic

 

    return 0;

}

 

//other functions

-------------------------------------------------

 

The compiler returns a single error message:

error C3867: 'My_NI::ChangeDetectionCallback': function call missing argument list; use '&CNIComm::ChangeDetectionCallback' to create a pointer to member

 

The line number for the error message corresponds to DAQ #4:

DAQmxErrChk (DAQmxRegisterSignalEvent(taskListen,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));

 

Further examination revels the explanation:

"Error: argument of type "int32 (__Cdecl My_NI::*) (TaskHandle taskHandle, void *callbackData) is incompatible with parameter of type "DAQmxSignalEventCallbackPtr"

 

I know the rest of the code works. It compiles and runs when the 5 shown DAQlines are commented out.

 

and... that's as far as I've gotten debugging. Anyone know what I've done wrong? For that matter, has anyone successfully used DAQmxRegisterSignalEvent callback with classes in c++?

 

0 Kudos
Message 1 of 3
(5,648 Views)
0 Kudos
Message 2 of 3
(5,637 Views)

Just in case anyone else is facing the same issue I've since learned that using direct callbacks with dynamic class functions in c++ is impossible. (Static class functions might allow direct callbacks)

 

The problem is that every class function is class instance specific, and the callback contains no provision for the class information. However, there are work arrounds.

 

Proper work arounds that maintain the object oriented aroach seem to require compiler specific 'cheats', template inheritance tricks, or builing your own custom library of routines.

 

A simpler work arround is to use a combination of a global function and global class pointer variables to relay the callback signal from the callback to the proper function.

 

I ended up doing something similar to this:

/------------------------------My_NI_Functions.h---------------------------------------------

//Global Callback

My_NI* forwardingAddress;

int32 CALLBACK ForwardFunction(TaskHandle taskListen, int32 signalID, void *callbackData)

{

    return forwardingAddress -> ChangeDetectionCallback(taskListen,signalID,callbackData);

}

 

 

//Class start

class My_NI

{

public:

    int 32 ChangeDetectionCallback(TaskHandle taskListen, int32 signalID, void *callbackData)

    {

        //Assorted Logic

        return 0;

    }

 

    My_NI( void) //Constructor

    {

        //callback request

        DAQmxErrChk (DAQmxCreateTask("",&taskListen));
        DAQmxErrChk (DAQmxCreateDIChan(taskListen,"Dev1/port0/line4","",DAQmx_Val_ChanPerLine));
        DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskListen,"Dev1/port0/line4",NULL,DAQmx_Val_ContSamps,1));

        forwardingAddress = this;
        DAQmxErrChk (DAQmxRegisterSignalEvent(taskListen,DAQmx_Val_ChangeDetectionEvent,0,ForwardFunction,NULL));
        DAQmxErrChk (DAQmxGetTaskNumChans(taskListen,&numLines));

    }

}

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

 

If for some reason you have multiple class objects then I believe you can replace the 'NULL' in DAQmxRegisterSignalEvent with an index number or other distinguish variable that will reapear again at the *callbackData pointer of the callback function. That reference data combined with a pointer table or similar should alow the forwarding function to send the callback to the correct destination class. However since I haven't personaly tried this, no promices. 

Message 3 of 3
(5,621 Views)