首先是一些关于我正在做的与火呼吸有关的背景。
然后,假设主查看器和计划视图都被加载为“主查看器”和“planview”,我将按下面的方式将文档插入计划查看器,
planview.attach(mainviewer.doc);
(the signature is "bool attach(const FB::JSObjectPtr& myDoc)" and
The mainviewer.doc is just a firebreath JSAPI)问题是,在firefox中,通过调用
FB::JSAPIPtr jsAPI = myDoc->getJSAPI(); // THIS WILL RETURN **NULL**.
m_main_doc = FB::ptr_cast<LcFbViewerDocumentAPI>(jsAPI); // Cast to my document API.只有当主机浏览器是firefox时才会出现此问题,IE/Chrome运行良好。
那么,当使用firefox时,通过的JSAPI发生了什么变化呢?
发布于 2013-03-08 05:53:34
事实证明,大多数浏览器(包括FireFox)在允许将它们传递到另一个函数调用之前对NPObjects进行包装;因此,您无法获得最初传递给浏览器的底层C++类。因为FireBreath无法访问真正的JSAPI ( FireBreath用来包装JSAPI对象给浏览器的NPObject ),所以也不能访问原始的JSAPI对象。
考虑为JSAPI对象的每个实例创建一个静态id。然后,您可以将instance_id公开为JSAPI属性,然后创建一个全局std::map,用于存储映射以获取对象。
// 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();
}当然,这最终会泄漏少量的内存,如果你从来没有经过地图和清除过期的弱ptrs,但它应该给你所需要的。当您得到一个应该是JSAPIPtr对象的对象时,您可以期望它是一个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
}
}
}我还没有测试过上面的代码,但是应该非常接近。
https://stackoverflow.com/questions/15286464
复制相似问题