从v8::Arguments到c++类型的转换

Converting from v8::Arguments to C++ Types

本文关键字:类型 c++ 转换 v8 Arguments      更新时间:2023-10-16

我正在用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)

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

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

这就是我迷路的地方。我不知道如何从参数中获取值,并将它们转换为常规的c++类型,所以我可以将值传递给我的send函数。据我所知,传递给Mailer::sendEmail的3个值将在args[0]args[1]args[2]中可用。我甚至知道我可以做一些类型检查,如if (!args[0]->IsArray()),但实际上将args[0]转换为std::list<std::string>是我不知道如何做的。

编辑:我找到了一种hack的方法来做这件事,但我仍然认为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());
}

我知道这是一个古老的话题,但我倾向于这样做:

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

如果您正在使用NaN(节点的本地抽象),那么试试下面的代码:

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

我能找到的转换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]);