On Mon, Jul 8, 2013 at 9:35 AM, Lyndsey <[email protected]> wrote: > I know that others have posted questions about this here and elsewhere. > However, I generally find either the question or the answer (or both) to be > either too vague or too old (or both). > > I simply want to wrap a C++ class so that it can be exposed in Javascript, > like so: > >> var myPoint = new Point(3,4); >> print(myPoint.x); //Assume print is defined and works splendidly > > > The Point example, of course, is taken directly from the V8 Embedder's > Guide. However, I had to tweak it significantly just to get it to compile > and run (Win x64 Debug). I also used a 2009 blog post by Alex Iskander. > This StackOverflow posting that referred me there offers a little > clarification but not much. > > The specific problem I'm having is that a Point can be constructed fine but > its member, x, cannot be accessed. I set breakpoints in the C++ getter > function called GetPointX but they are never reached. The Javascript > snippet above prints "undefined" instead of "3" as desired. I think I must > be missing something simple. Perhaps I'm not associating pointTemplate or > instance_templ back to something else, like the Point constructor or the > global context? > > Note: At the moment, I am not interested in memory management or even the > ability to set x. Or y. I just want to get this part working as a minimal > proof-of-concept. Maybe a function (rather than a property) on the Point > class would be my next step (i.e. myPoint.inverse() where x and y are > swapped or something). But I'm not there yet. > > I've included as much code as I think is necessary below. Please let me > know if more is needed and I'd be happy to supply it. Thanks in advance for > your help! > >> //The Point C++ class >> class Point { >> public: >> Point(int x, int y) : x_(x), y_(y) { } >> int x_, y_; >> }; > > >> >> //The method where I start doing V8 things. Set up an Isolate, Context, >> etc. Only the relevant parts are shown here. >> bool MyTest::DoStuff(...) >> { >> ... >> Local<FunctionTemplate> constructor = >> FunctionTemplate::New(ConstructPoint); >> context->Global()->Set(String::New("Point"), constructor->GetFunction()); > > >> >> pointTemplate = FunctionTemplate::New(); >> Local<ObjectTemplate> instance_templ = pointTemplate->InstanceTemplate(); >> instance_templ->SetInternalFieldCount(1); >> instance_templ->SetAccessor(String::New("x"), GetPointX); >> ... >> } > > >> >> //The Point constructor function >> void MyTest::ConstructPoint(const FunctionCallbackInfo<Value>& args) >> { >> //start a handle scope >> HandleScope handle_scope; >> >> //get an x and y >> int x = args[0]->Int32Value(); >> int y = args[1]->Int32Value(); >> >> //generate a new point >> Point *point = new Point(x, y); >> >> //return the wrapped point >> WrapPoint(point); >> } > > >> >> //The wrapper function >> Handle<Object> MyTest::WrapPoint(Point *pointToWrap) >> { >> //enter a handle scope >> HandleScope handle_scope; >> >> //create a new point instance >> Local<Object> point_instance = >> pointTemplate->GetFunction()->NewInstance(); >> >> //set that internal field >> point_instance->SetInternalField(0, External::New(pointToWrap)); >> >> //to prevent the point_instance from being destroyed when its >> //scope handle_scope is, use the Close() function >> return handle_scope.Close(point_instance); >> } > > >> >> //The getter function for "somePoint.x" in Javascript. The guts of this >> could be wrong. Sadly, I am never getting here at all! >> void MyTest::GetPointX(Local<String> name, const >> PropertyCallbackInfo<Value>& info) >> { >> Local<Object> self = info.Holder(); >> Local<External> wrap = >> Local<External>::Cast(self->GetInternalField(0)); >> void* ptr = wrap->Value(); >> int value = static_cast<Point*>(ptr)->x_; >> info.GetReturnValue().Set(Number::New(value)); >> }
There is a bug in your WrapPoint() function, it creates and wraps a new (JS) Point instance rather than wrapping the instance that's passed to your constructor. Make it wrap args.This() and things should work okay. -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
