5

自从我使用 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";

输出:

函数();// { 用户名:“”,密码:“”,服务:“登录”}
函数('1');// { 用户名:“1”,密码:“”,服务:“登录” }
函数('1','2');// { 用户名:“1”,密码:“2”,服务:“登录” }
func('a', 'b', 'c'); // { 用户名:“a”,密码:“b”,服务:“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";
4

4 回答 4

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

    ...
}
于 2012-05-09T21:42:29.577 回答
3

这段代码非常适合我从一行中的 v8 值中提取字符串值:

std::string tempString(*v8::String::Utf8Value(args[someInteger]));

std::string 构造函数应该处理您的默认场景,而不需要额外的代码,但如果您确实需要手动检查空值,这很简单。

这段代码作为示例,它获取所有参数的字符串值并将它们打印到标准输出,当然也将它们放入一个不错的数组中,因为打印它们有什么用?

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;
}
于 2012-06-19T18:45:11.653 回答
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 也会发生同样的事情。

于 2013-03-12T07:05:56.987 回答
0
string bi = info[0]->IsUndefined() ? "backwardIndex.dat" : string(*Nan::Utf8String(info[0]));
于 2016-03-18T06:17:43.707 回答