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

发布于 2024-10-03 19:33:10 字数 1608 浏览 0 评论 0原文

我试图将函数指针(类型为 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: nomatching function for call to QScriptEngine::newFunction() 注意:候选者是:...

如何将 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();
 }

I am trying to pass a function pointer (of type QScriptEngine::FunctionSignature (= QScriptValue (QScriptContext *, QScriptEngine *))) to an other function. But the function I need to pass is a member function of a class.

I use it like this:

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);
    }
};

With this example I get the error:

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

How can I pass the print function to newFunction?

EDIT:

I fixed it like this:

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();
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北方的巷 2024-10-10 19:33:10

这是行不通的,因为函数不是方法,所以签名是不同的。与其他语言不同,在 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 作为上下文的属性传递而不是作为引擎,但这就是想法 您的方法需要一个静态包装器,并在参数中的某个位置使用对象来应用您的函数。

That doesn't work because a function is not a method and so the signature are different. As opposed to other language, in C++ a method is not bound to an object, so it as the signature of a method and need to be applied on a object.

What you should do is wrap a proper function which (or a static one) with the good signature and call the method you want on the object passed as argumment.

like

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.

}

Maybe you would like instead to pass your_class as an attribute of the context rather than being the engine, but that's the idea. You need a static wrapper to your method with somewhere in the argument the object to apply your function on it.

枕梦 2024-10-10 19:33:10

仅传递成员函数引用可能会遇到的问题是成员函数需要一个对象实例来执行。如果是这样,请查看 Boost.bind,特别是 这部分。假设您希望对 MyClass 类型的当前对象使用 print() 方法,您可能需要如下所示的内容:

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() 。

The problem you may have with just passing the member function reference is that the member function needs an object instance to execute against. If so, have a look at Boost.bind, in particular, this part. Assuming that you want the print() method to the current object of your MyClass type, you might want something like this:

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));
    }
};

This will probably cause you to rework setProperty() a little.

浅忆流年 2024-10-10 19:33:10

不幸的是,C++ 中无法传递需要常规函数指针的成员函数。
指向成员函数的指针不是函数指针,只能与对象指针结合使用。

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

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

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

  3. 如果您关心性能,不关心可移植性,知道什么是调用约定,请查看开源 libffi 库 (http://sourceware.org/libffi/),它允许您在运行时构造函数指针。对于普通的 Qt 应用程序来说,这太过分了。

Unfortunately, there is no way in C++ to pass a member function where a regular function pointer is expected.
A pointer to a member function is NOT a function pointer, and can only be used in conjunction with an object pointer.

You will have to write a static function and get a pointer to your MyClass object from "somewhere else":

  1. There might be a way to store a pointer to your object into some "user data" or "context" field of the QScriptEngine or QScriptContext objects that will get passed to your function? Read the documentation to find out if the Qt developers were nice to you.

  2. Use a global std::map to associate one of your MyClass objects with each QScriptEngine.

  3. If you care about performance, don't care about portability, know what a calling convention is, have a look at the open-source libffi library (http://sourceware.org/libffi/), which allows you to construct function pointers at runtime. For your average Qt application, this is way overkill.

も星光 2024-10-10 19:33:10

尝试限定标识符:

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

编辑:

正如我看到函数的声明一样,您必须按照其他建议使用boost::bind

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

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

Try qualifying the identifier:

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

EDIT:

As I see the declaration of the function, you have to use boost::bind as other suggested:

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

boost::bind converts the method and the object to be called (this) into an object that can call that method on the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文