2010-11-23 67 views
2

我試圖將函數指針(類型爲QScriptEngine::FunctionSignature(= QScriptValue (QScriptContext *, QScriptEngine *)))傳遞給其他函數。但是我需要傳遞的函數是一個類的成員函數。在C++中傳遞成員函數指針

我用這樣的:

class MyClass 
{ 
    SomeVarType someVarINeedAccessTo; 

    QScriptValue print(QScriptContext* context, QScriptEngine* engine) 
    { 
     ... someVarINeedAccessTo ... 
    } 

    void someFunction() 
    { 
     QScriptEngine engine; 
     QScriptValue printFunction = engine.newFunction(print); 
     engine.globalObject().setProperty("print", printFunction); 
    } 
}; 

有了這個例子中,我得到的錯誤:

error: no matching function for call to QScriptEngine::newFunction(<unresolved overloaded function type>) note: candidates are: ...

如何傳遞的打印功能newFunction?

編輯:

我固定它是這樣的:

class MyClass 
{ 
    public: 
     ... 

     class TheEngine : public QScriptEngine 
     { 
      public: 
        MyClass* instance; 
     }; 

     static QScriptValue print(QScriptContext *context, QScriptEngine *engine); 

     void someFunction(); 

     ... 
}; 

Myclass::someFunction() 
{ 
    TheEngine engine; 

    ... 

    QScriptVaue printFunction = engine.createFunction(print); 
    engine.globalObject().setProperty("print", printFunction); 

    ... 
} 

QScriptValue MyClass::print(QScriptContext* context, QScriptEngine* engine) 
{ 
     TheEngine* eng = dynamic_cast<TheEngine*>(engine); 
     eng->instance->doSomething(...); 
     return engine->undefinedValue(); 
} 
+0

下面的鏈接可能會有所幫助,如果您有沒有碰到過它已經來了:http://www.parashift.com/c++-faq-lite/pointers-to-members.html – Tom 2010-11-23 15:33:54

回答

1

這不起作用,因爲函數不是一種方法,所以簽名是不同的。與其他語言相反,在C++中,方法不會綁定到對象,所以它作爲方法的簽名並需要應用於對象。

你應該做的是包裝一個適當的函數(或一個靜態的)與良好的簽名,並調用你想要的方法作爲argumment傳遞的對象。

MyClass : public QScriptEngine { 
    static QScriptValue static_print(QScriptContext* context, QScriptEngine* engine) 
    { 
    MyClass *my_engine = dynamic_cast<MyClass>(engine) 
    my_engine->print(context); 
    } 

// redefine print to take only one argument. 

}

也許你想,而不是作爲上下文的屬性通過your_class而不是發動機,但是這是想法。你需要一個靜態包裝到你的方法中,並在參數中的某個地方應用你的函數。

0

嘗試出線標識符:

QScriptValue printFunction = 
    engine.newFunction(&MyClass::print); 

編輯:

正如我看到decla該功能的口糧,你必須使用boost::bind或其他建議:

QScriptValue printFunction = 
    engine.newFunction(boost::bind(&MyClass::print, this, _1, _2)); 

boost::bind方法和對象被稱爲(this)轉換成一個對象,可以調用該對象上的方法。

+0

我得到`錯誤:沒有用於調用QScriptEngine :: newFunction(QScriptValue(MyClass :: *)(QScriptContext *,QScriptEngine *))的匹配函數` – VDVLeon 2010-11-23 14:58:54

+0

這意味着您的`QScriptEngine :: newFunction`方法不接受正確的函數簽名。那是什麼定義? – 2010-11-23 15:00:45

+0

像我發佈的:`QScriptValue(QScriptContext *,QScriptEngine *)` – VDVLeon 2010-11-23 15:01:20

0

剛剛通過成員函數引用時可能會遇到的問題是成員函數需要一個對象實例來執行。如果是這樣,看看Boost.bind,特別是this part。假設你想要的print()方法,以您的MyClass類型的當前對象,你可能想是這樣的:

class MyClass 
{ 
    SomeVarType someVarINeedAccessTo; 

    QScriptValue print(QScriptContext* context, QScriptEngine* engine) 
    { 
     ... someVarINeedAccessTo ... 
    } 

    void someFunction() 
    { 
     QScriptEngine engine; 
     engine.globalObject().setProperty("print", 
      boost::bind(&MyClass::print, this, _1, _2)); 
    } 
}; 

這可能會導致你返工的setProperty()一點點。

0

不幸的是,C++沒有辦法在需要常規函數指針的地方傳遞成員函數。 指向成員函數的指針不是函數指針,只能與對象指針一起使用。

你必須寫一個靜態函數,並從「別處」獲得一個指向你的MyClass的對象:

  1. 有可能是一個指向你的對象儲存到一些「用戶數據的方式「或」上下文「字段的QScriptEngine或QScriptContext對象將傳遞給你的函數?閱讀文檔以瞭解Qt開發人員是否對你很好。

  2. 使用全局std :: map將您的一個MyClass對象與每個QScriptEngine關聯。

  3. 如果您關心性能,不關心可移植性,知道調用約定是什麼,請查看開源libffi庫(http://sourceware.org/libffi/),該庫允許你在運行時構造函數指針。對於您的平均Qt應用程序,這是過度的。