Function call missing argument list to create pointer

和自甴很熟 提交于 2019-12-10 17:11:40

问题


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.


回答1:


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)




回答2:


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()




回答3:


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 );


来源:https://stackoverflow.com/questions/23207942/function-call-missing-argument-list-to-create-pointer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!