【发布时间】: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]->IsArray()),但实际上将 args[0] 转换为 std::list<std::string> 是我不知道该怎么做的。
编辑:我发现了一种骇人听闻的方法,但我仍然认为 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 说得很客气