我正在尝试将函数指针(类型为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();
}
答案 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对象的指针:
可能有一种方法可以将指向对象的指针存储到QScriptEngine或QScriptContext对象的某些“用户数据”或“上下文”字段中,这些字段将传递给您的函数?阅读文档以了解Qt开发人员是否对您好。
使用全局std :: map将一个MyClass对象与每个QScriptEngine相关联。
如果您关心性能,不关心可移植性,知道调用约定是什么,请查看开源libffi库(http://sourceware.org/libffi/),允许您在运行时构造函数指针。对于你的平均Qt应用程序,这是有点矫枉过正。