我尝试通过VRPN服务器将我的应用程序连接到OpenViBE。我的应用程序运行良好,直到我尝试添加代码将我的应用程序连接到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();
}
我在哪里做错了?感谢所有回复。
答案 0 :(得分:15)
我在Visual Studio中遇到了类似的错误:"function call missing argument list; use '&className::functionName' to create a pointer to member"
..
我在调用getter时错过了括号,所以className.get_variable_a()
答案 1 :(得分:3)
错误消息告诉您您提供的参数与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 );
答案 2 :(得分: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 to pointer,感谢rpavlik)