编辑:/*是否有可能通过 JSAPI 继承的信封访问 javascript 中的非 JSAPI 类对象。像下面这样的东西。*/
class DataPersonal
{
public:
std::string GetName()
{
return "ABC";
}
};
class Envelop:FB::JSAPIAuto
{
public:
Envelop(){
registerMethod("GetData", make_method(this, &Envelop::GetData));
}
DataPersonal* GetData()
{
return new DataPersonal();
}
};
/*
在 JavaScript 中
alert(plugin0.GetData().GetName());
其中 plugin0 是信封*/
原因是DataPersonal的源代码不可用,它是编译形式,所以我不能更改DataPersonal类。有什么解决方法吗?
我有点困惑。 究竟是什么让你认为有一种方法可以在不使用 registerMethod 或 registerProperty 的情况下访问 Javascript 中C++对象的成员?JSAPIAuto 类存在是有原因的,这个原因是在 javascript 和 C++ 之间提供一个接口。
使"_name"可访问的唯一方法是使用 registerProperty 和一个 getter/setter 来获取/设置 _name 或在 GetName 上注册方法,在 SetName 上注册方法。
也许我真的不明白你的问题或你想做什么?
如果你使用 getter 方法和 setter 方法注册属性,那么从 javascript 中,你将像普通成员一样使用它:
// In C++ in the constructor
registerProperty("_name", make_property(this, &MyClassAPI::get_name, &MyClassAPI::set_name));
// In the javascript
myPlugin._name = "Bobb";
alert(myPlugin._name);
这有帮助吗? Javascript 对C++或C++类型一无所知,因此您不能直接向它公开C++类;它只不过是一个指向JavaScript的不透明指针。 在幕后创建了一个NPObject*,它包装了JSAPI类型,并根据需要将值等转换为值和从中转换,这是FireBreath使用起来如此方便的原因之一。
编辑:您修改后的问题更有意义。 基本上,可以通过将 JSAPI 对象与指向内部对象的指针和指向您希望它调用的方法的函数指针make_method来执行您所描述的操作,如下所示:
class DataPersonal
{
public:
std::string GetName()
{
return "ABC";
}
};
class Envelop : FB::JSAPIAuto
{
public:
Envelop() {
registerMethod("GetName", make_method(&m_data, &DataPersonal::GetName));
}
private:
DataPersonal m_data;
};
正如您在示例中所看到的,您不能只返回指向类的指针并期望它工作 - 它不会。 如果是这样,我们就不需要像 JSAPI 这样的复杂类来包装它来使其工作。 但是,据我所知,只要参数和返回类型都与 JSAPI 兼容,make_method就没有理由不能包装来自另一个类的方法。 诀窍是确保您使用的指针的生命周期(在本例中为 &m_data
)与 JSAPI 类相关联;否则,您可能会遇到对象已被释放但 JavaScript 仍然想要使用它的情况。
当然,您需要为要公开的内部类上的每个属性或方法注册一个属性或方法。如果它们中的任何一个具有与 JSAPI 不兼容的参数或返回类型(很可能,考虑到所有因素),您只需在 JSAPI 对象上添加一个包装函数,该函数在内部对象上调用该函数。 简而言之,您将 JSAPI 类用作内部类上的方法和对象的包装器。
JSAPI尽可能多地使用任意函数进行自动转换;完全不可能将随机类类型交给javascript并使其理解。
我不认为你可以这样做,你想从Javascript访问的每个C++对象都应该从FB::JSAPIAuto继承,你不能只返回一个在Javascript中不起作用的C++指针。
可以使用以下方式访问其他C++对象及其方法或属性。
class MyJSAPIClass : public FB::JSAPIAuto
{
public:
MyJSAPIClass(const MyPluginPtr& plugin, const FB::BrowserHostPtr& host)
{
// Register your c++ object as a read only property
registerProperty("myCppObject",
make_property(this, &MyJSAPIClass ::GetMyCppMethod));
}
FB::JSAPIPtr GetMyCppMethod() { return m_cpp_object; }
private:
MyCPPClassPtr m_cpp_object;
}
FB_FORWARD_PTR(MyCPPClass)
class MyCPPClass : public FB::JSAPIAuto
{
public:
MyCPPClass()
{
_name="My name is...";
// Register your get name as a read only property
registerProperty("name",
make_property(this, &MyCPPClass::GetName));
}
std::String GetName()
{
return _name;
}
private:
std::string _name;
}
然后,在你的Javascript代码中,你可以访问你的姓名形式MyCPPClass,如下所示,
plugin.myCppObject.name