Вызов функции отсутствует список аргументов для создания указателя

Я пытался подключить свое приложение к OpenViBE через сервер VRPN. Мое приложение работает хорошо, пока я не попытаюсь добавить код для подключения моего приложения к серверу VRPN.

Мой код выглядит так:

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

С этим кодом, когда я пытаюсь запустить свое приложение, я получаю:

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

Я пытаюсь редактировать код по совету об ошибке, но я получаю еще одну ошибку:

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

Я ищу вокруг, но не могу найти никакого подходящего решения.

методы checkChannels а также handle_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();
}

Где я делаю ошибку? Спасибо за все ответы.

3

Решение

Вы не можете напрямую вызывать нестатический метод класса, используя этот обратный вызов. Это потому, что метод ожидает вызова с классом this указатель.

Если вам не нужны данные из вашего класса, просто сделайте метод статичным. Если вам нужны данные из класса, вы можете создать статическую заглушку, которая принимает указатель класса в параметре userData и затем вызывает оригинальный метод. Что-то вроде:

Декларация:

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

Определение

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

Затем при вызове функции используйте:

vrpnAnalog->register_change_handler( this, handle_analog_stub );

(Обновлен до static_cast для указателя, спасибо rpavlik)

3

Другие решения

У меня была похожая ошибка в Visual Studio: "function call missing argument list; use '&className::functionName' to create a pointer to member"..

Я просто пропустил скобки при вызове геттера, поэтому className.get_variable_a()

15

Сообщение об ошибке сообщает, что указанный вами аргумент не совпадает vrpn_ANALOGCHANGEHANDLER, Вы не показали определение этого. Я проверил онлайн, и он предложил

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

так что я пойду с этим.

Ваш код пытается передать указатель на функцию-член, которая не может быть преобразована в указатель на функцию. Это потому, что указатель на член-функцию может быть вызван только для объекта, поэтому он не будет знать, какой объект использовать.

Если вы посмотрите на код, который вы «копируете», то увидите, что vrpn_analog_callback это бесплатная функция. Однако в вашем коде это функция-член. Вам нужно изменить свой код так, чтобы обратный вызов был свободной функцией (или статической функцией-членом).

Если ваше намерение состоит в том, чтобы обратный вызов вызывал функцию-член для того же объекта 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 );
3
По вопросам рекламы [email protected]