A firebreath JSAPI will not be recognized in firefox

巧了我就是萌 提交于 2019-12-03 16:02:16

As it turns out, most browsers (including FireFox) wrap NPObjects before letting them be passed into another function call; because of this, you can't get at the underlying C++ class that you originally passed to the browser. Because FireBreath can't get to the real NPJavascriptObject (the NPObject that FireBreath uses to wrap JSAPI objects to give to the browser) it can't get to the original JSAPI object either.

Consider creating a static id for each instance of your JSAPI object. You can then expose the instance_id as a JSAPI property and then create a global std::map that you can use to store a map to get at your object.

// in the class def
static int counter;
int instance_id;

// In the .cpp file
int MyPluginAPI::counter(0);

std::map<int, FB::JSAPIWeakPtr> apiMap;
FB::JSAPIPtr getJSAPIObjectById(int id) {
    std::map<int, FB::JSAPIWeakPtr> fnd = apiMap.find(id);
    if (fnd != apiMap.end()) {
        return fnd.second->lock(); // it's a weak pointer, lock to get the shared_ptr
    } else {
        return FB::JSAPIPtr(); // Alternately throw an exception
    }
}

MyPluginAPI::MyPluginAPI() {
    instance_id = counter++;
    // Note that you can't get at the shared_ptr in the constructor,
    // so you'll have to call an init function after creating the JSAPI object

    registerProperty("instance_id",
                 make_property(this,
                    &FBTestPluginAPI::get_instId));
}

int MyPluginAPI::get_instId() { return instance_id; }

void MyPluginAPI::init() {
    apiMap[instance_id] = shared_from_this();
}

This would of course eventually leak a small amount of memory if you don't ever go through the map and clear out expired weak ptrs, but it should give you what you need. When you get an object that should be a JSAPIPtr object you can expect it as a JSObjectPtr.

void doSomethingWithAnAPI(const FB::JSObjectPtr& obj) {
    if (obj) {
        int id = obj->GetProperty("instance_id");
        FB::JSAPIPtr ptr = getJSAPIObjectById(id);
        if (ptr) {
            // Hurray! We have the object
        }
    }
}

I haven't tested the above code, but it should be pretty close.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!