Node.js插件类成员函数

Node.js addon class member functions

本文关键字:成员 函数 插件 js Node      更新时间:2023-10-16

在javascript对象中公开C++类的静态成员函数的代码类似于以下

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

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

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

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已经支持这一点,或者有人设计了一个更好的解决方案。

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

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());

在我看来,没有办法使用非静态方法来代替静态方法。有两个事实可以作为论据:

  • 在node.js文档中可以找到的所有代码示例都促进了静态函数的使用,因此开发人员并不意味着要再次使用他们的库(实际上我从未遇到过任何其他方法)

  • 由于node.js回调函数是用"static"修饰符声明的,因此您实际上需要一些类实例来调用任何实例方法。传统的方法是从"Arguments"中获取实例。您也可以使用一些"静态"指针指向传递给js代码的实例,但它只适用于一个实例。如果您想创建更多,那么在调用回调时将无法区分它们(当然,如果您不使用一些更复杂的技巧)。

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