【问题标题】:Converting from v8::Arguments to C++ Types从 v8::Arguments 转换为 C++ 类型
【发布时间】:2011-09-19 19:21:47
【问题描述】:

我正在使用 C++ 创建 Node.js 模块,但我对 v8::Arguments 类感到困惑。假设我有一个用于发送电子邮件的 Javascript 类,它有一个带有此签名的方法:

Mailer::sendEmail(Array recipients, String sender, String message);

会这样调用:

mailer.sendEmail(["joe@gmail.com", "sally@gmail.com"], "fred@gmail.com", "Hi there");

现在在 C++ 领域,我有一个带有这个签名的类函数:

SendEmail(const v8::Arguments& args)

在 Javascript 领域支持我的 Mailer::sendEmail 方法。 SendEmail 函数将创建我的 Emailer 类的一个新实例,它本身有一个具有此签名的类函数:

send(std::list<std::string> recipients, std::string from, std::string message)

这就是我迷路的地方。我不知道如何从 args 中获取值,并将它们转换为常规的 C++ 类型,因此我可以将这些值传递给我的 send 函数。据我了解,传递给 Mailer::sendEmail 的 3 个值将在 args[0]args[1]args[2] 中可用。我什至知道我可以进行一些类型检查,例如 if (!args[0]-&gt;IsArray()),但实际上将 args[0] 转换为 std::list&lt;std::string&gt; 是我不知道该怎么做的。

编辑:我发现了一种骇人听闻的方法,但我仍然认为 V8 有一些内置方法可以更简洁地处理此问题。

static Handle<Value> SendEmail(const Arguments& args)
{
    HandleScope scope;

    list<string> values;
    Local<Object> obj = args[0]->ToObject();
    Local<Array> props = obj->GetPropertyNames();

    // Iterate through args[0], adding each element to our list
    for(unsigned int i = 0; i < props->Length(); i++) {
        String::AsciiValue val(obj->Get(i)->ToString());
        values.push_front(string(*val));
    }

    // Display the values in the list for debugging purposes
    for (list<string>::iterator it = values.begin(); it != values.end(); it++) {
        cout << *it << endl;
    }

    return scope.Close(args.This());
}

【问题讨论】:

  • @Thomas 这个答案痛苦地含糊不清。此外,毫无疑问,在 V8 中将 args 转换为 c++ 类型的正确方法。
  • @mellowsoon 说得很客气

标签: c++ node.js v8


【解决方案1】:

如果您使用的是 NaN (native abstractions for node),请尝试以下代码:

std::string myString(*NanAsciiString(args[0])); 

【讨论】:

  • NanAsciiString 已被删除。请改用Nan::Utf8String。例如,std::string arg0 = *Nan::Utf8String(info[0]);
【解决方案2】:

我知道这是一个较老的话题,但我倾向于这样做的方式如下:

Handle<Value> MethodName (const Arguments& args) {

    // get the param
    v8::String::Utf8Value param1(args[0]->ToString());

    // convert it to string
    std::string foo = std::string(*param1);    

}

【讨论】:

  • 虽然不吸引人,但我很确定您可以将上述内容折叠成:std::string param1(*v8::String::Utf8Value(args[0]-&gt;ToString()));
【解决方案3】:

我能找到的在 JS 类型和 C++ 类型之间相互转换的最佳方法是使用 v8-juice,它提供了类型转换方法。具体来说,我使用的是 v8-convert,它是 v8-juice 的衍生产品,仅包含转换方法。

将 args[0] 转换为 std::list 只需一行:

std::list<std::string> values = cvv8::CastFromJS<std::list<std::string> >(args[0]);

【讨论】:

  • 关于 V8 Juice 的警告:code.google.com/p/v8-juice ACHTUNG ACHTUNG ACHTUNG:截至 2013 年 8 月 19 日,由于 2013 年上半年对核心 v8 做出的不兼容更改程度,该项目已被放弃. v8 API 正在以与每一个使用 v8 的方式不兼容的方式发生巨大变化......
猜你喜欢
  • 2020-11-22
  • 2015-11-01
  • 1970-01-01
  • 2015-11-17
  • 1970-01-01
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多