简体   繁体   中英

Pass a class' member function in to a callback function?

I have this template:

template <class T>
v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args)
{
    T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
    if (t != NULL) t->volume(args[0]->NumberValue());
    return args.This();
}

I want to make it 100% dynamic, so I'm hoping to replace t->volume with a pointer (std::mem_fn?). The thing is, I can't figure out from similar examples/questions how to retain the jsFunctionTemplate's current type (it must be a v8::InvocationCallback )

typedef Handle<Value> (*InvocationCallback)(const Arguments& args);

So that it's usage can still be:

audio->PrototypeTemplate()->Set("Volume", v8::FunctionTemplate::New(&jsFunctionTemplate<Audio>));

I am not opposed to using even C++11 syntax.

I don't claim to fully understand the limitations which the v8 API imposes here, but if a template argument for the type is all right, then I hope you can use a pointer-to-member template argument for what you want to achieve here. The following self-contained and tested example, although without v8, should demonstrate how this can be done:

#include <iostream>

struct foo {
  void bar(int arg) {
    std::cout << "bar(" << arg << ") called" << std::endl;
  }
};

template<class T, void (T::*fun)(int)>
void ptfWrapup(void* ptr, int arg) {
  (static_cast<T*>(ptr)->*fun)(arg);
}

int main() {
  foo f;
  ptfWrapup<foo, &foo::bar>(&f, 42);
}

Applied to your situation, and assuming NumberType to be the return value of that NumberValue call, or more importantly the type of the first argument of the functions you want to call, it would look something like this:

template <class T, void (T::*fun)(NumberType)>
v8::Handle<v8::Value> jsFunctionTemplate(const v8::Arguments &args)
{
    T *t = static_cast<T*>(args.This()->GetPointerFromInternalField(0));
    if (t != NULL) (t->*fun)(args[0]->NumberValue());
    return args.This();
}

… v8::FunctionTemplate::New(&jsFunctionTemplate<Audio, &Audio::volume>) …

In contrast to the example above, this here is untested, but on the other hand closer to your code. Together they should make the idea crystal clear, I hope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM