在C ++中传递成员函数指针

时间:2010-11-23 14:51:20

标签: c++ qt member-function-pointers

我正在尝试将函数指针(类型为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: ...

如何将打印功能传递给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 个答案:

答案 0 :(得分: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作为上下文的属性而不是引擎传递,但这就是想法。你需要一个静态的包装器,你可以在参数中的某个地方使用你的函数来实现它。

答案 1 :(得分:0)

尝试限定标识符:

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

修改

当我看到该函数的声明时,您必须使用boost::bind作为其他建议:

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

boost::bind将方法和要调用的对象(this)转换为可以在对象上调用该方法的对象。

答案 2 :(得分: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()。

答案 3 :(得分:0)

不幸的是,C ++中没有办法传递一个需要常规函数指针的成员函数。 指向成员函数的指针不是函数指针,只能与对象指针一起使用。

您必须编写一个静态函数并从“其他地方”获取指向MyClass对象的指针:

  1. 可能有一种方法可以将指向对象的指针存储到QScriptEngine或QScriptContext对象的某些“用户数据”或“上下文”字段中,这些字段将传递给您的函数?阅读文档以了解Qt开发人员是否对您好。

  2. 使用全局std :: map将一个MyClass对象与每个QScriptEngine相关联。

  3. 如果您关心性能,不关心可移植性,知道调用约定是什么,请查看开源libffi库(http://sourceware.org/libffi/),允许您在运行时构造函数指针。对于你的平均Qt应用程序,这是有点矫枉过正。