0

現在、XMLとJavascriptに基づいてユーザーインターフェイスを実装しています。私はたくさんのラッパークラスを作成しましたが、これまでのところすべてが正常に機能しています。私を悩ませていることが1つだけあります。関数の1つのパラメーターから永続オブジェクトを作成できません。私が次の機能を持っているとしましょう:

void UIManager::registerJSObject(JSObjectPtr objPtr) {

ラッパーを使用してJavascriptに登録されるJSObject(v8 :: Handleをラップする)はローカル関数パラメーターを指しているため、関数の後で消去されます。今では明らかにそれは私がやりたいことではありません。

私の最初のアプローチは、次のようにmakePersistentメソッドをJSObjectクラスに追加することでした。

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

そしてidは、buttonClicked関数を呼び出したり、UI.load関数だけでなく後でいくつかのフィールドを設定したりするのが好きです。

私が何かを見逃しているかどうか、またはこれがバグであるかどうか誰かが知っていますか?

あいさつムエペ

4

1 に答える 1

0

わかりました、私は解決策を見つけました。私はすでに正しい方向に進んでおり、永続ハンドルの作成は元のオブジェクトで行う必要があるため、特にJSObjectを取得する必要があるパラメーターに対して、2番目のオーバーロードで拡張メンバー関数を変更しました。

前に見たように:

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

JSObjectPtrのObjectWrap::unwrapで興味深い部分があります:

    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を使用しなくなったときに(実際に収集する必要があるときに)呼び出される弱参照に変換します。

于 2013-03-26T00:04:52.213 に答える