Pregunta

EDIT: /* Is it possible to access the non JSAPI class object in javascript via JSAPI inherited envelop. Some thing like below. */

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();
    }

};

/*

In JavaScript

alert(plugin0.GetData().GetName());

Where plugin0 is Envelop */

The reason for this is the source code of DataPersonal is not available, It is in compiled form So I cant alter the DataPersonal class. Any workaround for this?

¿Fue útil?

Solución

I'm a little confused. What exactly makes you think that there would be a way to access members of a C++ object in Javascript without using registerMethod or registerProperty? There is a reason that the JSAPIAuto class exists, and that reason is to provide an interface between javascript and C++.

The only way to make "_name" accessible would be to use registerProperty and a getter/setter that get/set _name or registerMethod on a GetName and registerMethod on a SetName.

Perhaps I don't really understand your question or what you are trying to do?

if you registerProperty with a getter method and a setter method then from javascript you will use it like a normal member:

// 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);

Does that help at all? Javascript knows nothing about C++ or C++ types, so you can't directly expose a C++ class to it; it wouldn't be anything but an opaque pointer to javascript. Behind the scenes an NPObject* is created that wraps the JSAPI type and converts values and such to and from as needed, it's one of the reasons that FireBreath is so convenient to use.


EDIT: Your revised question makes more sense. Basically it might be possible to do what you describe by having the JSAPI object make_method with a pointer to the internal object and the function pointer to the method you want it to call, like so:

    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;
};

As you can see in the example, you cannot just return a pointer to a class and expect it to work -- it won't. If it did, we wouldn't need a complex class like JSAPI to wrap it to make it work. However, as far as I know there is no reason that make_method can't wrap a method from another class as long as the parameter and return types are all compatible with JSAPI. The trick is to make sure that the lifecycle of the pointer you use (in this case &m_data) is tied to your JSAPI class; otherwise you could have a case where the object has been freed but javascript still wants to use it.

You would of course need to register a property or method for each property or method on the inner class that you want to expose. If any of them had parameters or return types that are not compatible with JSAPI (which is likely, all things considered) you can just add a wrapper function on the JSAPI object that calls the function on the inner object. In short, you use the JSAPI class as a wrapper to the methods and object on the inside class.

JSAPI does about as much automatic conversion with arbitrary functions as is possible; it's not at all possible to just hand a random class type to javascript and have it understand.

Otros consejos

I don't think you can do this, every your C++ object that you want to access from Javascript should be inherited from FB::JSAPIAuto, you can't just return a C++ pointer which won't work in Javascript.

you can use the following way to access other C++ objects and their methods or properties.

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;
}

Then, in your Javascript code you can access your name form MyCPPClass as below,

plugin.myCppObject.name
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top