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.


Reply via email to