2

QScriptEngine::FunctionSignature関数ポインター (型(= QScriptValue (QScriptContext *, QScriptEngine *))) を他の関数に渡そうとしています。しかし、渡す必要がある関数は、クラスのメンバー関数です。

私はこのように使用します:

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

print 関数を 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();
 }
4

4 に答える 4

1

関数はメソッドではなく、署名が異なるため、これは機能しません。他の言語とは対照的に、C++ ではメソッドはオブジェクトにバインドされていないため、メソッドのシグネチャとしてオブジェクトに適用する必要があります。

あなたがすべきことは、適切な関数(または静的関数)を適切な署名でラップし、引数として渡されたオブジェクトで必要なメソッドを呼び出すことです。

お気に入り

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 を渡したいと思うかもしれませんが、それがアイデアです。メソッドの静的ラッパーが必要で、引数のどこかに関数を適用するオブジェクトが必要です。

于 2010-11-23T15:14:49.543 に答える
0

識別子を修飾してみてください。

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

編集:

関数の宣言を見ると、boost::bind他の提案どおりに使用する必要があります。

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

boost::bindメソッドと呼び出されるオブジェクト ( this) を、オブジェクトでそのメソッドを呼び出すことができるオブジェクトに変換します。

于 2010-11-23T14:54:34.450 に答える
0

メンバー関数参照を渡すだけで発生する可能性がある問題は、メンバー関数が実行対象のオブジェクト インスタンスを必要とすることです。もしそうなら、Boost.bind、特にこの部分を見てください。型の現在のオブジェクトに 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() を少し作り直す必要があります。

于 2010-11-23T15:08:50.843 に答える
0

残念ながら、C++ では、通常の関数ポインターが必要な場所にメンバー関数を渡す方法がありません。メンバー関数へのポインターは関数ポインターではなく、オブジェクト ポインターと組み合わせてのみ使用できます。

静的関数を作成し、MyClass オブジェクトへのポインターを「別の場所」から取得する必要があります。

  1. オブジェクトへのポインターを、関数に渡される QScriptEngine または QScriptContext オブジェクトの「ユーザー データ」または「コンテキスト」フィールドに格納する方法があるかもしれません。ドキュメントを読んで、Qt 開発者があなたに好意的だったかどうかを確認してください。

  2. グローバルな std::map を使用して、MyClass オブジェクトの 1 つを各 QScriptEngine に関連付けます。

  3. パフォーマンスを気にし、移植性を気にせず、呼び出し規約が何であるかを知っている場合は、関数ポインターを構築できるオープンソースの libffi ライブラリ (http://sourceware.org/libffi/) を参照してください。実行時に。平均的な Qt アプリケーションの場合、これはやり過ぎです。

于 2010-11-23T15:19:05.597 に答える