Search code examples
c++staticinstancev8

V8 FunctionTemplate Class Instance


I have the following class:

class PluginManager
{
public:
    Handle<Value> Register(const Arguments& args);
    Handle<ObjectTemplate> GetObjectTemplate();
};  

I want the Register method to be accessible from JavaScript. I add it to the global object like this:

PluginManager pluginManagerInstance;

global->Set(String::New("register"), FunctionTemplate::New(pluginManagerInstance.Register)); 

It throws the following error:

'PluginManager::Register': function call missing argument list; use '&PluginManager::Register' to create a pointer to member

I tried to do that, but it doesn't work either. And it's not correct, because I want it to call the Register method of the pluginManagerInstance.

Except for making the Register method static or global, any ideas?

Thanks.


Solution

  • You're trying to bind two things at once: the instance and the method to invoke on it, and have it look like a function pointer. That unfortunately doesn't work in C++. You can only bind a pointer to a plain function or a static method. So image you add a static "RegisterCB" method and register it as the callback:

    static Handle<Value> RegisterCB(const Arguments& args);
    ...FunctionTemplate::New(&PluginManager::RegisterCB)...
    

    Now where do you get the pluginManagerInstance from? For this purpose, most callback-registration apis in V8 have an additional "data" parameter that will get passed back to the callback. So does FunctionTemplate::New. So you actually want to bind it like this:

    ...FunctionTemplate::New(&PluginManager::RegisterCB,
                             External::Wrap(pluginManagerInstance))...
    

    The data is then available through args.Data() and you can delegate to the actual method:

    return ((PluginManager*)External::Unwrap(args.Data())->Register(args);
    

    This can surely be made a little easier with some macro.