代码之家  ›  专栏  ›  技术社区  ›  Muepe

从函数参数获取持久对象

  •  0
  • Muepe  · 技术社区  · 13 年前

    我目前正在实现基于XML和Javascript的用户界面。我已经写了很多包装器类,到目前为止一切都很好。只有一件事困扰着我。我无法从我的一个函数的参数中创建持久对象。假设我有以下功能:

    void UIManager::registerJSObject(JSObjectPtr objPtr) {
    

    它使用我的包装器注册到Javascript中,JSObject(包装v8::Handle)指向本地函数参数,因此在函数被删除后。现在显然这不是我想要的。

    我的第一种方法是向JSObject类中添加一个makePersistent方法,如下所示:

    void JSObject::makePersistent() {
        v8::Persistent<v8::Object> newObj = v8::Persistent<v8::Object>::New(mObject);
        mObject = newObj;
    }
    

    遗憾的是,它没有工作,对象仍然被垃圾收集。所以我想,当我在那里做的时候可能已经太晚了,因为某种原因,当它从回调的Arguments参数中获取时,它已经被转换了,我把包装器改成了这个(只是为了测试):

    template<uint32 size, typename T, typename... FullArgs, typename... Args>
    Res expand(const v8::Arguments& args, Args... curArgs) {
        return expand<size + 1, FullArgs...>(args, curArgs..., ObjectWrap::unwrap<T>(v8::Persistent<v8::Value>::New(args[size])));
    }
    

    遗憾的是,这也不起作用。我无法获得以javascript分配的对象的持久句柄。我在谈论这个代码:

    var frame = {
        xmlTemplate: "testXml.xml",
    
        onTemplateLoaded: function () {
            this.frame1.button1.Caption = "Test";
        },
    
        buttonClicked: function(button) {
            button.Caption = "Clicked";
        }
    };
    
    UIMgr.loadUIElement(frame);
    

    我想调用buttonClicked函数,或者设置一些字段,不仅在UI.load函数中,而且在以后。

    有人知道我是不是遗漏了什么,或者这是不是一个bug吗?

    问候Muepe

    1 回复  |  直到 13 年前
        1
  •  0
  •   Muepe    13 年前

    好的,我找到了解决方案。我已经走上了正轨,必须在原始对象上创建持久句柄,所以我用第二个重载修改了我的扩展成员函数,特别是对于应该得到JSObject的参数。

    和以前差不多:

        template<uint32 size, typename T, typename... FullArgs, typename... Args>
        typename std::enable_if<std::is_same<T, JSObjectPtr>::value, Res>::type expand(const v8::Arguments& args, Args... curArgs) {
            return expand<size + 1, FullArgs...>(args, curArgs..., ObjectWrap::unwrap<T>(v8::Persistent<v8::Value>::New(args[size])));
        }
    

    随着有趣的部分在ObjectWrap::unwrapforJSObjectPtr中进行:

        template<typename T>
        static typename std::enable_if<std::is_same<T, JSObjectPtr>::value, JSObjectPtr>::type unwrap(v8::Persistent<v8::Value> val) {
            v8::Persistent<v8::Object> objh = v8::Persistent<v8::Object>::Cast(val);
    
            return std::make_shared<JSObject>(objh);
        }
    

    以v8::Persistent的形式传递给函数,否则它将无法工作。

    JSObject有一个用于持久句柄的构造函数,并将其转换为弱引用,当没有人再使用JSObject时(实际上是在必须收集它的时候),就会调用该弱引用。