2011-09-19 28 views
28

Estoy jugando con la creación de módulos Node.js en C++, pero estoy perplejo en la clase v8 :: Arguments. Digamos que tengo una clase Javascript para enviar mensajes de correo electrónico, el cual tiene un método con esta firma:Conversión de v8 :: Argumentos a C++ Tipos

Mailer::sendEmail(Array recipients, String sender, String message); 

cual se llamaría así:

mailer.sendEmail(["[email protected]", "[email protected]"], "[email protected]", "Hi there"); 

Ahora en C tierra ++, tengo una función de clase con esta firma:

SendEmail(const v8::Arguments& args) 

Que está respaldando mi método Mailer :: sendEmail en Javascript land. La función SendEmail va a crear una nueva instancia de mi clase Emailer, que a su vez tiene una función de clase con esta firma:

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

Y aquí es donde estoy perdido. No sé cómo tomar los valores de args, y convertirlos en tipos regulares de C++, por lo que puedo pasar los valores a mi enviar la función. Según lo entiendo, los 3 valores pasados ​​a Mailer :: sendEmail estarán disponibles en args [0], args [1], y args [2]. Incluso entiendo que puedo hacer algún tipo de comprobación como if (!args[0]->IsArray()), pero en realidad convertir args [0] en std::list<std::string> es lo que no sé cómo hacer.

Edité: Encontré una forma hackosa de hacer esto, pero sigo pensando que V8 tiene algunos métodos integrados para manejar esto de una manera más limpia.

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()); 
} 
+1

@Thomas Esa respuesta es dolorosamente * * vaga. Además, hay maneras indudablemente correctas de convertir los args a tipos de C++ en V8. – mellowsoon

+0

@mellowsoon que lo está poniendo amablemente – hplbsh

Respuesta

6

La mejor manera que puedo encontrar para convertir desde y hacia tipos JS y tipos de C++, está utilizando v8-juice, que proporciona métodos de fundición de tipos. Específicamente, estoy usando v8-convert, que es un spin-off de v8-juice, que incluye solo los métodos de conversión.

args Conversión [0] para std :: lista es una línea:

std::list<std::string> values = cvv8::CastFromJS<std::list<std::string> >(args[0]); 
+4

Advertencia sobre el Jugo V8: https://code.google.com/p/v8-juice/ ACHTUNG ACHTUNG ACHTUNG: desde el 19 de agosto de 2013 este proyecto está siendo abandonado debido a la titulación de cambios incompatibles en el núcleo v8 realizados durante la primera mitad de 2013. La API v8 se está cambiando drásticamente de forma incompatible con cada uno de los v8-using .... – Logan

48

Sé que esto es un tema viejo, pero la forma en que tienden a hacer esto es como sigue:

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

} 
+2

Aunque no es attactive, estoy bastante seguro de que puede colapsar lo anterior en : 'std :: string param1 (* v8 :: String :: Utf8Value (args [0] -> ToString()));' –