2012-05-08 40 views
5

C++ kullandığımdan beri uzun bir zaman geçti ve başımı sert türlerin etrafına sardığımdan beri daha uzun bir süre geçti. Ben sadece bir argüman verilmediyse, bir argümanı v8'den almak için bir tek liner çalışıyorum.V8 işlevinden varsayılan argüman almak için en kısa yol (tek liner)?

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

Çıkışlar: Maalesef

 
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" } 

, yakın-to-ideal çözüm (herhangi bir fikir neden?) Benim için çalışmıyor Aşağıdaki:

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

Kabul ediyorum V8 hakkında çok fazla şey bilmiyorum, ama değiştireceğiniz bir C++ POV'den şüpheli görünüyor bana: ne zaman arg0/arg1/arg2'nin yıkıcıları çalışıyor? Bu tahripçiler tek linonuzda ne zaman çalışır? Sınıfın yıkıcısı çalıştırıldığında ayrılmış belleğe ne olur? – hvd

+0

Hah, oh Tanrım ...yani afaik (v8'deki her şeyin, bellek yönetimi için statik ve korkunç olduğu gerçeğinin yanı sıra her yerde her şeye erişmesi gereken bir JS motoru): args * fonksiyonu * döndüğünde * imha edilebilir ... ama .. çok mümkün v8, dahili "yığın izleme" için verilere kilitleniyor. Temel olarak, olumlu bir şekilde bilmiyorum, bittiğinde kodu kesinlikle profillendireceğim. ;) –

+0

Döşenmiş bir gömlek tam olarak "en temiz" çözümler değildir. –

cevap

8

Vyacheslav Egorov çivilenmiş onun yorumuyla, diziye eriştiğimde, imha edilmişti.

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

Kullanımı Örnek: Sonuçta ben kullanarak sona erdi

v8::Handle<v8::Value> myMethod(const v8::Arguments &args) { 
    char *username = get(args[0], "user"); 
    char *password = get(args[1], "pass"); 

    ... 
} 
+2

P.S. Kendimden daha iyi bir cevabı kabul edeceğim. Kendi sorularımı cevaplamaktan gerçekten nefret ediyorum. –

3

Bu kod biraz tek satırda bir v8 değerinden bir dize değeri çıkarmak için benim için iyi çalıştı:

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

std :: string yapıcısı, ek kod gerektirmeden varsayılan senaryolarınızı kullanmalıdır, ancak boş değerleri el ile denetlemeniz gerekiyorsa, bu önemsizdir.

Bu kod örnek olarak işlev görür, tüm argümanların dize değerlerini alır ve bunları stdout'a yazdırır ve elbette onları güzel bir diziye sokar, çünkü hangi kullanım onları yazdırıyor? AsciiValue bu tek kapsam dışında gitti olmasıdır

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! 
... 

:

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

Egorov, geçici AsciiValue amacı kompakt gösterimde akıllı işaretçi gibi otomatik tahrip edilmiş doğrudur hat kapsamı sadece bir kez dize değeri kullanmak isteyen varsa

{ 
    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. 

hala kullanmak mükemmel Tamam,: Eğer 'önbelleğe' gösterici defalarca kullanmayı düşünüyorsanız yerine

, 2 çizgilerle bölmek gerekir kompakt notasyonu:

doSomethingWithString(*v8::String::Utf8Value(args[0]->ToString())); //OK 

doSomethingWithString fonksiyonu ile çalışmak için doğru değeri alır. Sadece ondan döndüğünüzde, otomatik imha ise Utf8Value.

Aynı şey String :: AsciiValue için de geçerlidir.

0
string bi = info[0]->IsUndefined() ? "backwardIndex.dat" : string(*Nan::Utf8String(info[0]));