2012-04-26 21 views
10

Bare conmigo mientras explico esto.¿Cómo pasar un objeto C++ envuelto a una devolución de llamada de Javascript?

Estoy tratando de escribir un módulo Node.js, usando C++, que envuelve y expone algunas clases de libhdf5.

Actualmente estoy interesado en dos clases de libhdf5. El primero es File y abre un archivo hdf5. El segundo es Group, y representa grupos dentro de ese archivo. Obtiene objetos de grupo desde un objeto de archivo.

He escrito un código en el que creo un objeto File e intento obtener un Group de él. Estoy intentando hacer que mi módulo Node.js sea lo más Javascript posible, así que quiero devolver el grupo usando una devolución de llamada. Por lo tanto, estoy tratando de codificar mi módulo de manera que se usa así:

var hdf5 = require('hdf5'); 
var file = new hdf5.File('/tmp/example.h5'); 
file.getGroup('foobar', function (err, group) { console.log(group); }); 

Por lo tanto, en el código C++ para mi File envoltorio, tendría una función que se asigna a la función getGroup aquí, y Llamaría a la función anónima proporcionada, pasando cualquier error, así como la nueva envoltura de objetos Group.

Dado que esto me sonaba como que la documentación de Node.js muestra que es factory of wrapped objects, he modelado mi código Group después de los ejemplos allí.

Por lo tanto, tengo mi contenedor Group codificado, pero estoy atascado tratando de crear una instancia. Aún no sé lo suficiente como para saber cómo alejarme del uso de la clase v8 Arguments para los parámetros de función. Debido a eso, parece que no puedo pasar algunos parámetros que necesito para mi función de constructor persistente v8 (porque estoy instanciando esto desde C++, y no desde JS-land).

¿Alguien podría echar un vistazo a my code for libhdf5 y darme un puntero sobre cómo lograr esto? Siento que casi estoy allí, pero me estoy perdiendo algo.

Aquí es mi Group envoltorio, la función constructora destacó: https://github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72

Aquí es mi File envoltura, con la línea hightlighted donde tendría que pasar en mis parámetros, como argumentos (o lo que es lo que necesito cambiar esto para que esto funcione: https://github.com/ryancole/node-hdf5/blob/master/src/h5_file.cc#L110

gracias de antemano, y gracias por leer este muro de texto :)

Respuesta

9

Usted está casi allí.. No necesita pasar Arguments a Group::Instantiate. Simplemente pase lo que necesita y use el constructor para crear la nueva instancia de Group. Por ejemplo:

Handle<Value> Group::Instantiate(const std::string& name) { 
    HandleScope scope; 

    Local<v8::Value> argv[1] = { 
     Local<v8::Value>::New(String::New(name.c_str())) 
    }; 

    return scope.Close(Constructor->NewInstance(1, argv)); 
} 

El método Group::New hace el resto del trabajo de construcción.

Handle<Value> Group::New(const Arguments& args) { 
    HandleScope scope; 

    if (!args[0]->IsString()) { 
     return ThrowException(Exception::TypeError(String::New("First argument must be a string"))); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Group * const group = new Group(name); 
    bar->Wrap(args.This()); 

    return args.This(); 
} 

En File::OpenGroup se puede hacer esto:

Handle<Value> File::OpenGroup (const Arguments& args) { 
    HandleScope scope; 

    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsFunction()) { 
     ThrowException(Exception::SyntaxError(String::New("expected name, callback"))); 
     return scope.Close(Undefined()); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Local<Function> callback = Local<Function>::Cast(args[1]); 

    const unsigned argc = 2; 
    Local<Value> argv[argc] = { 
     Local<Value>::New(Null()), 
     Local<Value>::New(Group::Instantiate(name)) 
    }; 
    callback->Call(Context::GetCurrent()->Global(), argc, argv); 

    return scope.Close(Undefined()); 
} 

HTH

+0

Es lo que quiere decir que se necesita un método de fábrica ('Grupo :: Instantiate') para devolver una instancia de otra clase ? – ZachB

Cuestiones relacionadas