C++ 函数调用缺少参数列表来创建指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23207942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:22:04  来源:igfitidea点击:

Function call missing argument list to create pointer

c++qt5.2vrpn

提问by Sk1X1

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.

我试图通过 VRPN 服务器将我的应用程序连接到 OpenViBE。我的应用程序运行良好,直到我尝试添加代码以将我的应用程序连接到 VRPN 服务器。

My code looks like this:

我的代码如下所示:

MainWindow.ccode:

MainWindow.c代码:

#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.hcode:

MainWindow.h代码:

#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 checkChannelsand handle_analogI "copy" from this code, where all works fine:

方法checkChannelshandle_analog我从此代码“复制”,一切正常:

#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.

我在哪里做错了?感谢所有回复。

采纳答案by The Dark

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 thispointer.

您不能使用此回调直接调用非静态类方法。这是因为该方法期望使用类this指针调用。

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:

如果您不需要类中的任何数据,则只需将方法设为静态即可。如果确实需要类中的数据,则可以创建一个静态“存根”,该存根采用 userData 参数中的类指针,然后调用原始方法。就像是:

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)

(更新为 static_cast 到指针,感谢 rpavlik)

回答by Justin Hirsch

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

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

我只是在调用 getter 时缺少括号,所以 className.get_variable_a()

回答by M.M

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

错误消息告诉您您提供的参数不匹配vrpn_ANALOGCHANGEHANDLER。你没有显示那个定义。我在网上查了一下,它建议

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_callbackis 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).

如果您查看正在“复制”的代码,您会发现这vrpn_analog_callback是一个免费功能。但是在您的代码中,它是一个成员函数。您需要更改代码,以便回调是一个自由函数(或静态成员函数)。

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:

如果您的意图是回调应该在您注册处理程序的同一个 MainWindow 对象上调用成员函数,请执行以下操作:

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