Search code examples
javascriptc++node.jsv8

Unwrapping objects members with V8/Node.JS


I'm learning V8/Node.JS through one of my project and I'm wondering if there is a way to unwrap a C++ object inherited from node::OjectWrap (from the Node.JS API) and its members at the same time.

All examples I can found have int members for instance and any of them try to wrap C++ object members. Here is a code explanation of what I want to do:

// A very basic class which only contains a vector member
// Note that it does not interact with any V8 or Node.JS code
class B
{
  public:
  // Constructors and methods...
  size_t getSize(void) { return vec_.size(); };

  private:
    std::vector<int> vec_;
} 

// The class I instanciate correctly in my Javascript code
class A : public node::ObjectWrap
{
  public:
    static void Init(v8::Handle<v8::Value> exports);
    static v8::Handle<v8::Value> New(const v8::Arguments& args); // The method I use to instanciate my JS object
    static v8::Handle<v8::Value> Update(const v8::Arguments& args); // A method I call

  private:
    A(B b) : b_(b) {};
    ~A(void);

  private:
    static v8::Persistent<v8::Function> constructor_;
    B b_;
}

To keep things simple, here is the definitions of A::New and A::Update. I'm using the Google V8 documentation sample code for the others methods.

v8::Handle<v8::Value> A::New(const v8::Arguments& args)
{
  v8::HandleScope scope;

  if (args.IsConstructorCall())
  {
    B b;
    // Fill the vector of B with n elements...
    // If I print here the size of a->b_.size(), I get n

    A* a = new A(b);
    A->Wrap(args.This());

    return args.This();
  }
  else
    // ...
}

v8::Handle<v8::Value> A::Update(const v8::Arguments& args)
{
  v8::HandleScope scope;

  A* a = ObjectWrap::Unwrap<A>(args.This());
  // If I print here the size of a->b_.size(), I get a garbage value
}

Finally, my JavaScript code:

var a = new addon.A(/* Constructor parameters *); // Will print the good size value
a.Update(); // Will print the garbage value

It seems that the B member of A is not wrapped correctly. So my question is: is it possible to wrap the object members without inherited them of node::ObjectWrap ?

Thanks for your help.


Solution

  • For those who may be in the same situation, I found out what was my error.

    In fact, I was allocating the B member on the stack and since the method we call in the A class are statics, you can only have access to garbage values between two calls (here A::New and A::Update).

    I solve the problem allocating the B object on the heap.