I tried to connect my app to OpenViBE through VRPN server. My app works well until I try to add code to connect my app to VRPN server.

My code looks like this:

MainWindow.c code:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtUiTools/QUiLoader>
#include <QFile>
#include <QMessageBox>
#include <QFileDialog>

#include <iostream>
using namespace std;

#include "vrpn_Analog.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    currentImage = 0;
    labelSize = ui->label_2->size();

    createActions();
    openFileDialog();
}
void MainWindow::checkChannels()
{
    vrpn_Analog_Remote *vrpnAnalog = new vrpn_Analog_Remote("Mouse0@localhost");
    vrpnAnalog->register_change_handler( 0, handle_analog );
}


void VRPN_CALLBACK MainWindow::handle_analog( void* userData, const vrpn_ANALOGCB a )
{
 int nbChannels = a.num_channel;

 cout << "Analog : ";

 for( int i=0; i < a.num_channel; i++ )
 {
 cout << a.channel[i] << " ";
 }

 cout << endl;
}

MainWindow.h code:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileInfoList>

#include "vrpn_Analog.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void resizeEvent(QResizeEvent *);

private slots:
    void openFileDialog();    

private:    
    void checkChannels();

    void VRPN_CALLBACK handle_analog( void* userData, const vrpn_ANALOGCB a );

};

#endif // MAINWINDOW_H

With this code, when I try to run my app I get:

error: C3867: 'MainWindow::handle_analog': function call missing argument list; use '&MainWindow::handle_analog' to create a pointer to member

I try to edit code by error advice, but I get another error:

error: C2664: 'vrpn_Analog_Remote::register_change_handler' : cannot convert parameter 2 from 'void (__stdcall MainWindow::* )(void *,const vrpn_ANALOGCB)' to 'vrpn_ANALOGCHANGEHANDLER'
There is no context in which this conversion is possible

I search around, but I don't find any usable solution.

Methods checkChannels and handle_analog I "copy" from this code, where all works fine:

#include <QtCore/QCoreApplication>
#include <iostream>
#include "vrpn_Analog.h"


void VRPN_CALLBACK vrpn_analog_callback(void* user_data, vrpn_ANALOGCB analog)
{
    for (int i = 0; i < analog.num_channel; i++)
    {
        if (analog.channel[i] > 0)
        {

            std::cout << "Analog Channel : " << i << " / Analog Value : " << analog.channel[i] << std::endl;
        }
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    /* flag used to stop the program execution */
    bool running = true;

    /* VRPN Analog object */
    vrpn_Analog_Remote* VRPNAnalog;

    /* Binding of the VRPN Analog to a callback */
    VRPNAnalog = new vrpn_Analog_Remote("openvibe_vrpn_analog@localhost");
    VRPNAnalog->register_change_handler(NULL, vrpn_analog_callback);

    /* The main loop of the program, each VRPN object must be called in order to process data */
    while (running)
    {
        VRPNAnalog->mainloop();
    }

    return 0;

    return a.exec();
}

Where I'm doing mistake? Thanks for all replies.

有帮助吗?

解决方案 3

You cannot directly call a non-static class method using this callback. This is because the method is expecting to be called with the class this pointer.

If you don't need any data from your class, then just make the method static. If you do need data from the class, you can make a static "stub" that takes the class pointer in the userData parameter and then calls the original method. Something like:

Declaration:

static void VRPN_CALLBACK handle_analog_stub( void* userData, const vrpn_ANALOGCB a );

Definition

void VRPN_CALLBACK MainWindow::handle_analog_stub( void* userData, const vrpn_ANALOGCB a )
{
   MainWindow *mainWindow = static_cast<MainWindow*>(userData);
   mainWindow->handle_analog(NULL, a);
}

Then when you call the function use:

vrpnAnalog->register_change_handler( this, handle_analog_stub );

(Updated to static_cast to pointer, thanks rpavlik)

其他提示

I had a similar error in Visual Studio: "function call missing argument list; use '&className::functionName' to create a pointer to member"..

I was just missing the parenthesis when calling the getter, so className.get_variable_a()

The error message tells you that the argument you provided does not match vrpn_ANALOGCHANGEHANDLER. You didn't show the definition of that. I checked online and it suggested

typedef void (*vrpn_ANALOGCHANGEHANDLER)(void *userdata, const vrpn_ANALOGCB info);

so I'm going with that.

Your code attempts to pass a pointer-to-member-function, which cannot be converted to a pointer-to-function. This is because a pointer-to-member-function can only be called on an object, so it wouldn't know what object to use.

If you look at the code you are "copying off", you will see that vrpn_analog_callback is a free function. However in your code it is a member function. You need to change your code so that the callback is a free function (or a static member function).

If your intent is that the callback should call the member function on the same MainWindow object that you are registering the handler on, then do this:

// In MainWindow's class definition, add this:
static void VRPN_CALLBACK cb_handle_analog( void* userData, const vrpn_ANALOGCB a )
{
    static_cast<MainWindow *>(userData)->handle_analog(NULL, a);
}

// In checkChannels()
vrpnAnalog->register_change_handler( this, cb_handle_analog );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top