Как передать завернутый объект С++ в обратный вызов Javascript?
Горе со мной, как я это объясняю.
Я пытаюсь написать модуль Node.js, используя С++, который обертывает и предоставляет некоторые классы из libhdf5.
В настоящее время меня интересуют два класса из libhdf5. Первый - File
, и он открывает файл hdf5. Второй - Group
, и он представляет группы внутри этого файла. Вы получаете объекты Group из объекта File.
Я написал код, в котором я создаю объект File
и пытаюсь получить от него Group
. Я пытаюсь сделать мой Node.js модуль как Javascripty насколько возможно, поэтому я хочу вернуть группу с помощью обратного вызова. Итак, я пытаюсь закодировать свой модуль так, чтобы он использовался следующим образом:
var hdf5 = require('hdf5');
var file = new hdf5.File('/tmp/example.h5');
file.getGroup('foobar', function (err, group) { console.log(group); });
Итак, в коде С++ для моей оболочки File
у меня была бы функция, которая отображается здесь в функции getGroup
, и она вызывала бы данную анонимную функцию, передавая любые ошибки, а также новая обтекающая оболочка Group
.
Учитывая, что это звучит для меня так, как выглядит документация Node.js как factory обернутых объектов, у меня есть смоделировал мой код Group
после примеров там.
Итак, у меня есть оболочка Group
, закодированная, но я пытаюсь создать экземпляр. Я пока не знаю достаточно, чтобы знать, как отклониться от использования класса v8 Arguments
для параметров функции. Из-за этого я, похоже, не могу передать некоторые параметры, которые мне нужны для моей постоянной функции конструктора v8 (потому что я создаю это из С++, а не из JS-land).
Кто-нибудь, пожалуйста, взгляните на мой код для libhdf5 и дайте мне указатель на то, как этого добиться? Я чувствую, что я почти там, но что я просто что-то пропустил.
Вот моя оболочка Group
, с выделенной функцией конструктора: https://github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72
Вот моя обертка File
, с строкой hightlighted, где мне нужно будет передать мои параметры, как Аргументы (или что бы это ни было, что мне нужно изменить это, чтобы это работало: https://github.com/ryancole/node-hdf5/blob/master/src/h5_file.cc#L110
Спасибо заранее, и спасибо за чтение этой стены текста.:)
Ответы
Ответ 1
Ты почти там. Вам не нужно передавать Arguments
в Group::Instantiate
. Просто передайте то, что вам нужно, и используйте конструктор для создания нового экземпляра Group
. Например:
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));
}
Метод Group::New
выполняет остальную часть строительной работы.
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();
}
В File::OpenGroup
вы можете сделать это:
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());
}
НТН