V8 Javascript引擎:V8::参数和函数模板 我封装了一个C++标准库 STD::MAP,我想把它作为No.js Advon公开。我想要两个函数,Set用于向哈希表添加新值,以及Get用于从映射中查找值。我想要一个可以用于“任意”类型的函数。这意味着Get必须从Args[0]中提取类型为T1的值(注意Args属于类型v8::Arguments)。请参阅下面的代码 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(); } 模板 类哈希:公共节点::ObjectWrap{ 公众: 静态v8::持久构造函数; 静态void Init(v8::Handle目标); 受保护的: /* ... */ 静态v8::Handle New(常量v8::Arguments和Args);//新对象 静态v8::句柄集(常量v8::参数和参数);//集H[x]=y 静态v8::Handle Get(const v8::Arguments和Args);//返回H[x] 私人: std::maph; }; /* ... */ 模板 v8::Handle Hash::Get(常量v8::Arguments和Args){ v8::手镜手镜; THash*H=ObjectWrap::Unwrap(Args.This()); //TODO:我想提取T1类型的参数Args[0],将其命名为x,然后 //返回参数y=H->get(x)类型为T2。 返回v8::Undefined(); }

V8 Javascript引擎:V8::参数和函数模板 我封装了一个C++标准库 STD::MAP,我想把它作为No.js Advon公开。我想要两个函数,Set用于向哈希表添加新值,以及Get用于从映射中查找值。我想要一个可以用于“任意”类型的函数。这意味着Get必须从Args[0]中提取类型为T1的值(注意Args属于类型v8::Arguments)。请参阅下面的代码 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(); } 模板 类哈希:公共节点::ObjectWrap{ 公众: 静态v8::持久构造函数; 静态void Init(v8::Handle目标); 受保护的: /* ... */ 静态v8::Handle New(常量v8::Arguments和Args);//新对象 静态v8::句柄集(常量v8::参数和参数);//集H[x]=y 静态v8::Handle Get(const v8::Arguments和Args);//返回H[x] 私人: std::maph; }; /* ... */ 模板 v8::Handle Hash::Get(常量v8::Arguments和Args){ v8::手镜手镜; THash*H=ObjectWrap::Unwrap(Args.This()); //TODO:我想提取T1类型的参数Args[0],将其命名为x,然后 //返回参数y=H->get(x)类型为T2。 返回v8::Undefined(); },javascript,c++,node.js,v8,embedded-v8,Javascript,C++,Node.js,V8,Embedded V8,有办法做到这一点吗?如果是,怎么做 如果无法提取任意类型,如果我愿意限制为几个预定义类型,那么最佳做法是什么?例如,T=int,T=std::string,T=MyType1和T=MyType2,T=MyType2,您需要将T1和T2转换为v8::Value的助手函数,反之亦然。问题是,这种转换是特定于类型的,因此您不会像建议的那样绕过每种类型的类型特征或重载函数。像这样的方法应该会奏效: #include <type_traits> // C++0x template<ty

有办法做到这一点吗?如果是,怎么做


如果无法提取任意类型,如果我愿意限制为几个预定义类型,那么最佳做法是什么?例如,
T=int
T=std::string
T=MyType1
T=MyType2
T=MyType2
您需要将
T1
T2
转换为
v8::Value
的助手函数,反之亦然。问题是,这种转换是特定于类型的,因此您不会像建议的那样绕过每种类型的类型特征或重载函数。像这样的方法应该会奏效:

#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);
}
#包括//C++0x
模板
T来自v8value(v8::句柄值)
{
if(std::is_same::value)
{
v8::String::Utf8Value stringValue(值);
返回std::string(*stringValue,stringValue.length());
}
else if(std::is_same::value)
返回值->整数值();
其他的
抛出新的std::异常(“不支持的类型”);
}
v8::句柄到V8Value(标准::字符串和值)
{
返回v8::String::New(value.c_str(),value.length());
}
v8::处理v8对象(int值)
{
返回v8::Number::New(值);
}
...
v8::Handle Hash::Set(常量v8::Arguments和Args)
{
T1键=fromV8值(Args[0]);
T2值=从V8值(参数[1]);
返回。。。;
}
v8::Handle Hash::Get(常量v8::Arguments和Args)
{
T1键=fromV8值(Args[0]);
T2值=。。。;
返回V8对象(值);
}

尝试
T1 x=*(T1*)Args[0]时会发生什么
?@AustinMullins:之所以崩溃,是因为V8不像
std::string
那样存储字符串。最有可能的情况是,这甚至不能正确地处理整数-即使这样,您也只是利用了一个无法依赖的实现细节。是的,我认为我的第一个问题的答案应该是“否”。你建议的带有类型特征的解决方案在我看来没问题。谢谢出于好奇,人们通常会这样做吗?(我的意思是,这被认为是“良好实践”吗?)另外,我是否可以避免使用标准库的
std::is_same
?@blazs:我不知道V8用户是如何做到这一点的——我从未见过代码在V8中做过类似的事情。至于std::是否相同?有什么问题吗?如果您担心多个
If
语句的速度会很慢,编译器将对它们进行优化。我不知道有什么更好的解决办法。函数重载也可以在这里工作,但您必须在没有参数的情况下工作。我不担心编译器没有对其进行优化或诸如此类的事情。只是我一直在使用V8和内部库,而内部库不使用C++的标准库,并且包含它(stdlib)只是为了在V8类型之间进行转换,这似乎有些过分。@blazs:V8本身使用stdlib。