I should also note that I forgot to change the comment above the GetPointX method. I am obviously reaching breakpoints in there now. :)
Also, I wholeheartedly agree about adding the check to ensure the constructor is being called "properly". I assume that will prevent Javascripters from constructing a Point with too few, too many, or incorrectly-typed arguments? On Monday, July 8, 2013 2:35:53 AM UTC-5, Lyndsey 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 <https://developers.google.com/v8/embed>. 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<http://create.tpsitulsa.com/blog/2009/01/29/v8-objects/>. > This StackOverflow > posting<http://stackoverflow.com/questions/3066833/how-do-you-expose-a-c-class-in-the-v8-javascript-engine-so-it-can-be-created-u>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)); >> } > > > > -- -- 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.
