2014-04-21 63 views
2

我試圖通過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("[email protected]"); 
    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("[email protected]"); 
    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)

+0

具體來說,一個函數指針的類型和指針的成員函數是不同的(因爲'this'指針等)。此外,不需要C風格的演員:你可以(應該)做'MainWindow * self = static_cast (userData);',或者如果你被允許使用'auto','auto self = static_cast (userData );'(在回調中調用'this''等價的指針'self''是我見過的常見習慣用法)。你可以調用一個非靜態成員,或者直接使用'self-> myMember'來訪問對象成員。 –

3

錯誤消息告訴您,您提供的參數不匹配vrpn_ANALOGCHANGEHANDLER。你沒有顯示這個定義。我在網上查了一下,它提示

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

所以我就這樣說。

您的代碼嘗試傳遞指向成員函數的指針,該函數無法轉換爲指向函數的指針。這是因爲只能在對象上調用指向成員函數的指針,所以它不知道要使用哪個對象。

如果你看看你「複製」的代碼,你會看到vrpn_analog_callback是一個免費的功能。但是在你的代碼中它是一個成員函數。您需要更改您的代碼,以便回調是一個免費函數(或靜態成員函數)。

如果意圖是回調應該叫您在註冊處理程序的相同主窗口對象的成員函數,那麼這樣做:

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

我在Visual Studio中類似的錯誤:"function call missing argument list; use '&className::functionName' to create a pointer to member" ..

調用獲取方法時,我只是缺少括號,所以className.get_variable_a()

+0

我剛剛開始在C#的長連勝後C++ ...您保存了我的培根xx –

+0

雖然這是一個相關的錯誤消息,並有這個答案在這裏可能會有所幫助一些搜索者,我認爲這是很重要的,要注意這一點實際上並沒有涉及問題的解決方案或解決方案 - 請參閱其他答案。 –

+0

@rpavlik當然對我有用!我認爲這對於所有在Java,C#和代碼完成上長大的我們的程序員都是相關的* _ * –