简体   繁体   English

V8 Javascript引擎:v8 ::参数和功能模板

[英]V8 Javascript engine: v8::Arguments and function templates

I wrapped a C++ standard library std::map<T1,T2> that I want to expose as a Node.JS addon. 我包装了一个C ++标准库std::map<T1,T2> ,我想将其公开为Node.JS插件。 I want to have two functions, Set for adding a new value to the hash table, and Get for looking up value from the map. 我想拥有两个功能: Set用于向哈希表添加新值,以及Get用于从地图中查找值的功能。 I want a single function that would work for "arbitrary" type. 我想要一个适用于“任意”类型的函数。 This means Get would have to extract value of type T1 from Args[0] (note that Args is of type v8::Arguments ). 这意味着Get必须从Args[0]提取类型T1值(请注意Args的类型为v8::Arguments )。 See the code below. 请参见下面的代码。

template<typename T1, typename T2>
class Hash : public node::ObjectWrap {
public:
    static v8::Persistent<v8::FunctionTemplate> constructor;
    static void Init(v8::Handle<v8::Object> target);
protected:
    /* ... */
    static v8::Handle<v8::Value> New(const v8::Arguments& Args); // new object 
    static v8::Handle<v8::Value> Set(const v8::Arguments& Args); // set H[x]=y
    static v8::Handle<v8::Value> Get(const v8::Arguments& Args); // return H[x]
private:
    std::map<T1, T2> H;
};
/* ... */
template<typename T1, typename T2>
v8::Handle<v8::Value> Hash<T1, T2>::Get(const v8::Arguments& Args) {
    v8::HandleScope HandleScope;

    THash<T1, T2>* H = ObjectWrap::Unwrap<Hash<T1, T2> >(Args.This());
    // TODO: I want to extract argument Args[0] of type T1, call it x, and then
    // return argument y=H->get(x) of type T2.
    return v8::Undefined();
}

Is there a way to do this? 有没有办法做到这一点? If yes, what is the way of doing it? 如果有,是什么做呢?

In case there is no way of extracting an arbitrary type, what is the best practice in case I am willing to restrict to several predefined types? 如果无法提取任意类型,如果我愿意限制为几种预定义类型,那么最佳实践是什么? For example, T=int , T=std::string , T=MyType1 , and T=MyType2 . 例如, T=intT=std::stringT=MyType1T=MyType2

You need helper functions that will convert from T1 and T2 to v8::Value and vice versa. 您需要将从T1T2转换为v8::Value以及反之亦然的辅助函数。 The problem is, this conversion is type-specific so you won't get around type traits or overloaded functions for each type as suggested here . 问题是,此转换是特定于类型的,因此您不会像这里建议的那样绕过类型特征或每种类型的重载函数。 Something like this should work: 这样的事情应该起作用:

#include <type_traits> // C++0x

template<typename T>
T fromV8Value(v8::Handle<v8::Value> value)
{
  if (std::is_same<T,std::string>::value)
  {
    v8::String::Utf8Value stringValue(value);
    return std::string(*stringValue, stringValue.length());
  }
  else if (std::is_same<T,int>::value)
    return value->IntegerValue();
  else
    throw new std::exception("Unsupported type");
}

v8::Handle<v8::Value> toV8Value(std::string& value)
{
  return v8::String::New(value.c_str(), value.length());
}

v8::Handle<v8::Value> toV8Object(int value)
{
  return v8::Number::New(value);
}

...

v8::Handle<v8::Value> Hash::Set(const v8::Arguments& Args)
{
  T1 key = fromV8Value<T1>(Args[0]);
  T2 value = fromV8Value<T2>(Args[1]);
  return ...;
}

v8::Handle<v8::Value> Hash::Get(const v8::Arguments& Args)
{
  T1 key = fromV8Value<T1>(Args[0]);
  T2 value = ...;
  return toV8Object(value);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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