Node.js addon类成员函数

时间:2012-12-11 10:35:37

标签: c++ node.js

在javascript对象中公开C ++类的静态成员函数的代码看起来像这样

tpl->InstanceTemplate()->Set( String::NewSymbol("thefunc"), FunctionTemplate::New(myclass::myfunc)->GetFunction() );

其中thefunc是可从javascript访问的函数的名称,该函数映射到类myfunc的静态成员myclass

由于该方法是静态的,我们必须通过一些实例指针访问所有类实例成员,并编写一些样板代码来获取它。例如:

static Handle<Value> myclass::myfunc( const Arguments &args )
{
    myclass *instance = Unwrap<myclass>( args.This() );
    // now use 'instance' like 'this'
    return True();
}

我想知道是否可以在接口中设置成员函数并将其绑定到类实例以避免使用样板的静态函数并将系统调用直接进入我的非静态方法,这样我就可以使用'this '指针。

我可以想到一种丑陋的方式,涉及#define扩展到包含代理函数的模板类,该代理函数展开'this'并转发对成员函数的所有调用,这将导致类似于此的设置代码:

DECLARE_MEMBER_FUNCTION( thefunc_handle, myclass, myfunc );
tpl->InstanceTemplate()->Set( String::NewSymbol("thefunc"), thefunc_handle );

但似乎Node.js已经支持这个或有人设计了一个更好的解决方案。

2 个答案:

答案 0 :(得分:4)

通过引入静态函数模板,您可以优雅地绑定成员方法:

class myclass : public node::ObjectWrap
{
    ...

    typedef v8::Handle<v8::Value> (myclass::*WrappedMethod)(const v8::Arguments& args);

    template<WrappedMethod m>
    static v8::Handle<v8::Value> Method(const v8::Arguments& args)
    {
        myclass* obj = ObjectWrap::Unwrap<myclass>(args.This());
        return (obj->*m)(args);
    }

    // Non-static member methods to be exported
    v8::Handle<v8::Value> func1(const v8::Arguments& args);
    v8::Handle<v8::Value> func2(const v8::Arguments& args);
    v8::Handle<v8::Value> func3(const v8::Arguments& args);
};

在你myclass::Init(Handle<Object> exports):

tpl->PrototypeTemplate()->Set(String::NewSymbol("func1"),
    FunctionTemplate::New(Method<&myclass::func1>)->GetFunction());
tpl->PrototypeTemplate()->Set(String::NewSymbol("func2"),
    FunctionTemplate::New(Method<&myclass::func2>)->GetFunction());
tpl->PrototypeTemplate()->Set(String::NewSymbol("func3"),
    FunctionTemplate::New(Method<&myclass::func3>)->GetFunction());

答案 1 :(得分:2)

在我看来,没有办法使用非静态方法而不是静态方法。有两个事实可以作为这个论点:

  • 你可以在node.js文档中找到的所有代码示例都促进了静态函数的使用,因此开发人员不会暗示他们的库的另一种用法(实际上我从未遇到任何其他方法)

  • 因为node.js回调函数是用'static'修饰符声明的,所以你基本上需要一些类实例来调用任何实例方法。传统方式是从“参数”中获取实例。您也可以使用一些“静态”指针指向传递给js代码的实例,但它仅适用于一个实例。如果你想创造更多,你将无法在调用回调时区分它们(当然,如果你不使用一些更复杂的技巧)。

总而言之,使用非静态功能是不可能的,因为没有简单合法的技术来操作它们