自从我使用C ++以来已经有很长一段时间了,甚至更长时间以来我一直围绕着硬类型。我只是在寻找一个工作一个衬里来从v8获取一个参数,或者在没有提供一个参数时使用默认值。
v8::String::Utf8Value arg0(args[0]);
v8::String::Utf8Value arg1(args[1]);
v8::String::Utf8Value arg2(args[2]);
const char *username = (args.Length() > 0) ? *arg0 : "";
const char *password = (args.Length() > 1) ? *arg1 : "";
const char *service = (args.Length() > 2) ? *arg2 : "login";
输出:
func(); // { username: "", password: "", service: "login" } func('1'); // { username: "1", password: "", service: "login" } func('1', '2'); // { username: "1", password: "2", service: "login" } func('a', 'b', 'c'); // { username: "a", password: "b", service: "c" }
不幸的是,以下接近理想的解决方案对我不起作用(任何想法为什么?):
const char *username = (args.Length() > 0) ? *v8::String::Utf8Value(args[0]->ToString()) : "";
const char *password = (args.Length() > 1) ? *v8::String::Utf8Value(args[1]->ToString()) : "";
const char *service = (args.Length() > 2) ? *v8::String::Utf8Value(args[2]->ToString()) : "login";
答案 0 :(得分:8)
维亚切斯拉夫·叶戈罗夫(Vyacheslav Egorov)用他的评论钉了它,当我访问该字符串时,它已被销毁。最终我最终使用了:
char *get(v8::Local<v8::Value> value, const char *fallback = "") {
if (value->IsString()) {
v8::String::AsciiValue string(value);
char *str = (char *) malloc(string.length() + 1);
strcpy(str, *string);
return str;
}
char *str = (char *) malloc(strlen(fallback) + 1);
strcpy(str, fallback);
return str;
}
用法示例:
v8::Handle<v8::Value> myMethod(const v8::Arguments &args) {
char *username = get(args[0], "user");
char *password = get(args[1], "pass");
...
}
答案 1 :(得分:3)
这段代码很适合我从一行中的v8值中提取字符串值:
std::string tempString(*v8::String::Utf8Value(args[someInteger]));
std :: string构造函数应该处理您的默认方案而不需要额外的代码,但如果您确实需要手动检查空值,这是微不足道的。
这段代码作为一个例子,它获取所有参数的字符串值并将它们打印到stdout,当然把它们放到一个很好的数组中,因为有什么用途将它们打印出来?
std::string* printAllArgs(const Arguments& args){
std::cout << "PRINTING ALL ARGS: ";
std::string* stringArray = new std::string[args.Length()];
for(int i = 0; i < args.Length(); i++){
std::string tempString(*v8::String::Utf8Value(args[i]));
stringArray[i] = tempString;
std::cout << tempString << ";";
}
return stringArray;
}
答案 2 :(得分:2)
Egorov是正确的,因为临时AsciiValue
对象已被自动销毁,就像紧凑符号中的智能指针一样:
const char *username = *v8::String::Utf8Value(args[0]->ToString());
//transient AsciiValue object has gone out of scope, and its destructor has been called in
// previous line, rendering the pointer (content) invalid henceforth!
...
这是因为AsciiValue
已超出该单行范围的范围。
相反,如果你打算多次使用'缓存'指针,应该把它分成2行:
{
v8::String::Utf8Value usernameObj(args[0]->ToString());
const char *username = *usernameObj;
...
//use username pointer as often as desired; it remains valid in this entire scope.
doSomethingWithString(username); //OK
//can also dereference Utf8Value object only when needed:
doSomethingWithString(*usernameObj); //OK
}
//here, usernameObj is out of scope and is destroyed, and username will become invalid.
如果只打算使用一次字符串值,那么使用紧凑表示法仍然完全可以:
doSomethingWithString(*v8::String::Utf8Value(args[0]->ToString())); //OK
doSomethingWithString
函数获取正确的值。只有从它返回,然后Utf8Value
如果自动销毁。
String :: AsciiValue也是如此。
答案 3 :(得分:0)
string bi = info[0]->IsUndefined() ? "backwardIndex.dat" : string(*Nan::Utf8String(info[0]));