title: make a CVICALLBACK a member function in QT creator
body: <p>I found an NI example on how to use some of the DAQmx functions. It's a simple C-file that contains some of the following:</p>
  
  <pre><code>...
  // This is a declaration/definition I think
  int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData);
  ...
  // Later in the script there is actual function
  
  int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
  {
      ...
  return 0;
  }
  </code></pre>
  
  <p>When I tend to use some of the variables or functions that are defined in .h file, the ChangeDetectionCallback function does not recognize them. I tried to define this callback function as a member function in .h file, hoping that now all functions will be accessible. Here's my .h content:</p>
  
  <pre><code>#ifndef MAINWINDOW_H
  #define MAINWINDOW_H
  
  #include &lt;QMainWindow&gt;
  #include "NIDAQmx.h"
  
  namespace Ui {
  class MainWindow;
  }
  
  class MainWindow : public QMainWindow
  {
  Q_OBJECT
  
  public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();
  
  int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData);
  
  private:
  Ui::MainWindow *ui;
  void mainLoop();
  };
  
  #endif // MAINWINDOW_H
  </code></pre>
  
  <p>and here's my .c content:</p>
  
  <pre><code>#include "mainwindow.h"
  #include "ui_mainwindow.h"
  #include "NIDAQmx.h"
  
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;time.h&gt;
  
  #define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
  
  MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
  {
  ui-&gt;setupUi(this);
  mainLoop();
  }
  
  MainWindow::~MainWindow()
  {
  delete ui;
  }
  
  void MainWindow::mainLoop()
  {
  ...
  DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
  ...    
  }
  
  
  
  
  int32 MainWindow::ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
  {
  ...
  return 0;
  }
  </code></pre>
  
  <p>So, again, I tried many wrong ways to define my callback function in the header file unsuccessfully. Please, help me to get this straight.
  And here's the error message that I do not clearly understand:</p>
  
  <pre><code>D:\Projects\sapm3\mainwindow.cpp:37: error: cannot convert 'MainWindow::ChangeDetectionCallback' from type 'int32 (MainWindow::)(TaskHandle, int32, void*) {aka long int (MainWindow::)(void*, long int, void*)}' to type 'DAQmxSignalEventCallbackPtr {aka long int (__attribute__((__cdecl__)) *)(void*, long int, void*)}'
       DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
  </code></pre>
  
  <p>Here's the original code. It triggers callback function to get a measurement sample and outputs the data to console. I wish to write the sampled data to my member variable and emit a signal that is defined in the .h file of the object.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;time.h&gt;
  #include &lt;NIDAQmx.h&gt;
  
  #define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error; else
  
  static TaskHandle   taskHandle;
  static uInt32       numLines;
  static uInt8        cachedData[200];
  
  int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData);
  void Cleanup (void);
  
  int main(void)
  {
  int32       error=0;
  char        errBuff[2048]={'\0'};
  
  /*********************************************/
  // DAQmx Configure Code
  /*********************************************/
  DAQmxErrChk (DAQmxCreateTask("",&amp;taskHandle));
  DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev1/port0/line0:7","",DAQmx_Val_ChanPerLine));
  DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"Dev1/port0/line0:7","Dev1/port0/line0:7",DAQmx_Val_ContSamps,1));
  DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
  DAQmxErrChk (DAQmxGetTaskNumChans(taskHandle,&amp;numLines));
  
  /*********************************************/
  // DAQmx Start Code
  /*********************************************/
  DAQmxErrChk (DAQmxStartTask(taskHandle));
  
  puts("Continuously reading. Press Enter key to interrupt\n");
  
  puts("Timestamp                 Data read   Changed Lines");
  
  getchar();
  
  Error:
  if( DAQmxFailed(error) )
  {
      DAQmxGetExtendedErrorInfo(errBuff,2048);
      Cleanup();
      printf("DAQmx Error: %s\n",errBuff);
  }
  printf("End of program, press Enter key to quit\n");
  getchar();
  return 0;
  }
  
  int32 CVICALLBACK ChangeDetectionCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
  {
  int32   error=0;
  uInt8   data[200]={0};
  int32   numRead;
  uInt32  i=0;
  char    buff[512], *buffPtr;
  char    errBuff[2048]={'\0'};
  char    *timeStr;
  time_t  currTime;
  
  if( taskHandle ) {
      time (&amp;currTime);
      timeStr = ctime(&amp;currTime);
      timeStr[strlen(timeStr)-1]='\0';  // Remove trailing newline.
  
      /*********************************************/
      // DAQmx Read Code
      /*********************************************/
      DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByScanNumber,data,8,&amp;numRead,NULL,NULL));
  
      if( numRead ) {
          buffPtr = buff;
          strcpy(buff, timeStr);
  
          strcat(buff,"  ");
          buffPtr = buff + strlen(buff);
          for(;i&lt;numLines;++i) {
              sprintf(buffPtr,"%d",data[i]);
              buffPtr++;
          }
  
          strcat(buff,"    ");
          buffPtr = buff + strlen(buff);
          for(i=0;i&lt;numLines;++i) {
              sprintf(buffPtr,"%c",data[i]==cachedData[i]?'-':'X');
              buffPtr++;
              cachedData[i] = data[i];
          }
          puts(buff);
          fflush(stdout);
      }
  }
  return 0;
  
  Error:
  if( DAQmxFailed(error) )
  {
      DAQmxGetExtendedErrorInfo(errBuff,2048);
      Cleanup();
      printf("DAQmx Error: %s\n",errBuff);
  }
  return 0;
  }
  
  void Cleanup (void)
  {
  if( taskHandle!=0 ) 
  {
      /*********************************************/
      // DAQmx Stop Code
      /*********************************************/
      DAQmxStopTask(taskHandle);
      DAQmxClearTask(taskHandle);
      taskHandle = 0;
  }
  }
  </code></pre>
  
  <p>I found the way to go around my problem. I declare an array variable at the top of the file. This way my callback function recognizes it. Then, I copy data from this array to my member array.
  Similarly, I created a counter variable and increment it each time the callback runs. At the same time I loopcheck this variable in my member function until it reaches desirable value and then emit a signal. Such approach really sucks and I wish to find a more intelligent way to writ it. </p>