Function Templates: Calling non-static member functions

752 views
Skip to first unread message

dominiek

unread,
Jan 7, 2010, 10:02:47 PM1/7/10
to v8-users
Hi there,

I'm writing a little plugin that allows you to use v8 in the Ruby
programming language. Right now I'm kind of having trouble with
creating a callback to a non-static member function. Basically, the
FunctionTemplate allows me to input a callback, but it's impossible to
simply reference a member function (more about the complexities of
that here: http://www.parashift.com/c++-faq-lite/pointers-to-members.html)

However, when reading the embedder's guide, it seems that you've
solved this problem already for accessors!

"The complexity of an accessor depends upon the type of data you are
manipulating:
* Accessing Static Global Variables
* Accessing Dynamic Variables
"

For the latter, you're using a special mechanism that allows you to
define a static wrapper function, which then uses AccessorInfo to get
a reference to the object. This means that it's possible to call
member functions (dynamic functions of a class instance) when you use
accessors.

However, it is not possible to use dynamic functions when you use a
FunctionTemplate. Is this correct?

Is there any hack you can think of that allows me to do it anyway?
Providing callbacks to non-static member functions is essential for
writing scripting language extensions.

Thanks!

P.S. My C++ is a bit rusty, but I've been digging into this problem
for quite some hours now.

Eric Ayers

unread,
Jan 7, 2010, 10:48:54 PM1/7/10
to v8-u...@googlegroups.com
Here's what I did.

http://pastebin.com/m31876b81

you still use static functions, but you associate a class instance
when you create the v8 object and then invoke a method on the
instance.

> --
> v8-users mailing list
> v8-u...@googlegroups.com
> http://groups.google.com/group/v8-users
>

--
Eric Z. Ayers
Google Web Toolkit, Atlanta, GA USA

Stephan Beal

unread,
Jan 8, 2010, 6:42:17 AM1/8/10
to v8-u...@googlegroups.com
On Fri, Jan 8, 2010 at 4:02 AM, dominiek <in...@dominiek.com> wrote:
Is there any hack you can think of that allows me to do it anyway?
Providing callbacks to non-static member functions is essential for
writing scripting language extensions.

A callback to a non-static member function always requires an instance of that class. Aside from that, binding a member function is very similar to binding a non-member function (with the additional step of decoding the native "this" object before calling the native member function).

The v8-juice project provides support for binding any of the following C++ constructs to v8:

- free functions
- member functions (if the class containing the member is also wrapped)
- member variables, either via the Accessor interceptors or by binding functions to them, such that the functions are called in place of the get/set operations.
- static variables, whether member or free.

You might find it useful for your project.

The main project page:
http://code.google.com/p/v8-juice/

Some useful wiki pages:

How the type conversions work:
http://code.google.com/p/v8-juice/wiki/ConvertingTypes
(that part is central to the whole binding mechanism)

Binding free functions:
http://code.google.com/p/v8-juice/wiki/BindingFunctions

Binding classes (including member funcs/variables):
http://code.google.com/p/v8-juice/wiki/ClassWrap


> P.S. My C++ is a bit rusty, but I've been digging
> into this problem for quite some hours now.

Given that: be aware that generic binding mechanisms require either code generators (i'm not aware of any for v8, unless one counts macros) or rather intricate templates-based mechanisms. Thus you may want to brush up on your C++ before undertaking any significant JS/C++ binding projects. Simple (or "brute force") bindings can be done without too much C++ know-how, but generic solutions to the problem require a fairly good understanding of C++ templates (or a hypothetical code generator).

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

cretz

unread,
Feb 22, 2010, 2:08:08 PM2/22/10
to v8-users
I am sorry to revive an old thread, but I am running in to the same
issue. I am trying to make a JSR-223 compatible Java bridge to V8. I
also need dynamic function binding. I am unable to see the pastebin
since it has expired. Can someone repost?

Also, I prefer to use pure V8 w/out the v8-juice project. Does anyone
know the best way to dynamically bind functions at runtime? I was
considering binding all functions to a single function and obtaining
some form of unique identification from the Arguments object. Any help
is appreciated.

On Jan 8, 5:42 am, Stephan Beal <sgb...@googlemail.com> wrote:

Abdulla Kamar

unread,
Feb 22, 2010, 7:00:34 PM2/22/10
to v8-u...@googlegroups.com
When you create a function with v8::FunctionTemplate::New(), you can optionally pass a v8::Value along with it. This value can be a pointer to a class that you can get when your callback is invoked by using v8::Arguments::Data(). Hopefully that helps.




--
Thank you
Abdulla

cretz

unread,
Feb 23, 2010, 1:16:03 PM2/23/10
to v8-users
That's what I ended up doing. I use an External to wrap a jobject. I
saw this method in the pyv8 project. So I am using the same callback
for every function and delegating based on the data in the Arguments.
Thanks again.

Seiji Sam Lee

unread,
Feb 23, 2010, 2:36:28 PM2/23/10
to v8-u...@googlegroups.com
Yes, it works!! But I need bind objects with c++ pointers, it seems more
natural the object has the c++ pointer and their methods/properties use it.

I have tested with ObjectTemplate::New() but it don't accept a data
parameter.

I have tested with SetInternalField but it only works with Global (after
context being created) not with objects into Global (you know, B, C, D in my
original email).

I need bind every object (not template) with a c++ pointer. There must be a
general (and simple) technique to do that.

Thanks in advance.

Abdulla Kamar

unread,
Feb 23, 2010, 5:59:39 PM2/23/10
to v8-u...@googlegroups.com
I don't do it this way, so this might not be quite correct, but I'm fairly certain you should be able to create a ObjectTemplate and SetInternalFieldCount to 1. After that you could create a NewInstance and SetPointerInInternalField to point to an instance of your class. From there, you could add your function to the object, and when the callback is invoked, you should be able to get the Object from Arguments::This() and GetPointerFromInternalField.
Reply all
Reply to author
Forward
0 new messages