在 javascript 中访问对象的成员C++而无需注册其成员



编辑:/*是否有可能通过 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

相关内容

  • 没有找到相关文章

最新更新