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

时间:2013-09-19 12:21:43

标签: c++ firebreath jsapi

修改 / * 是否可以通过JSAPI继承的envelop访问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是Envelop * /

原因是DataPersonal的源代码不可用,它是编译形式所以我不能改变DataPersonal类。 对此有何解决方法?

2 个答案:

答案 0 :(得分:3)

我有点困惑。究竟是什么让你认为有一种方法可以在不使用registerMethod或registerProperty的情况下在Javascript中访问C ++对象的成员?有一个原因是JSAPIAuto类存在,原因是提供javascript和C ++之间的接口。

使“_name”可访问的唯一方法是使用registerProperty和getter / setter获取/设置_Name或registerMethod对GetName和registerMethod的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尽可能多地使用任意函数进行自动转换;它根本不可能只是将随机类类型传递给j​​avascript并让它理解。

答案 1 :(得分:3)

我认为你不能这样做,你想从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