1

编辑: /* 是否可以通过 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 类。 有什么解决方法吗?

4

2 回答 2

3

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

使“_name”可访问的唯一方法是使用 registerProperty 和 getter/setter,它们在 GetName 上获取/设置 _name 或 registerMethod,在 SetName 上使用 registerMethod。

也许我真的不明白你的问题或你想要做什么?

如果您使用 getter 方法和 setter 方法 registerProperty 然后从 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 并让它理解。

于 2013-09-19T14:25:40.760 回答
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
于 2013-09-19T14:27:06.010 回答