1

I'm writing Agueas [1] addon for Node.js

For now I have synchronous code, C++ class looks like this:

class LibAugeas : public node::ObjectWrap {
public:
    static void Init(Handle<Object> target);

protected:
    augeas * m_aug;
    LibAugeas();
    ~LibAugeas();

    static Handle<Value> New(const Arguments& args);

    static Handle<Value> get        (const Arguments& args);
    static Handle<Value> set        (const Arguments& args);
    static Handle<Value> setm       (const Arguments& args);
    // other methods
};

Usage of this class in JS:

var lib = require('...');
var aug = new lib.Augeas(...);
aug.set(...);
aug.get(...);
// etc

I'm going to impelement asynchronous code.

The bottleneck is creating augeas object (aug_init) while all or some lenses and files are being loaded and parsed. So the idea is creating augeas object asynchronously, and then pass created JS object in a callback function:

  1. Pure C thread: call aug_init(), aug_load() to get augeas handle.
  2. When ready, use augeas handle to creat JS object (see the first snippet)
  3. Pass created JS object to callback function.

Usage might be as such:

lib.heracles(function(aug) {
        if (!aug.error()) {
            console.log('Hello!');

            // async save:
            aug.save(function(err, msg) {
                console.log(msg);
                });
        } else {
            console.log('Sad, but true :-(');
        }
    }
);

And finally, my problem: I do not know how to create JS object in C++ :-)

Constructor static Handle<Value> New(const Arguments& args); returns args.This(), but when I'm in C++ code I do not have args and also can't wrap object.

So, how do I create JS object in C++? Please, don't break my heart saying it is not possible :-)

[1] http://augeas.net

0

1 Answer 1

1

Ok, thanks to everyone :-) I've found the right way. Here is a static method which creates an JS object wrapping given augeas handle. Then I can pass this object to callback function from C++ code.

Local<Object> LibAugeas::New(augeas *aug)
{
    LibAugeas *obj = new LibAugeas();
    obj->m_aug = aug;

    Handle<ObjectTemplate> tpl = ObjectTemplate::New();
    tpl->SetInternalFieldCount(1); // one field for LibAugeas* pointer (via obj->Wrap())

#define _OBJ_NEW_METHOD(m) NODE_SET_METHOD(tpl, #m, m)
    _OBJ_NEW_METHOD(get);
    _OBJ_NEW_METHOD(set);
    _OBJ_NEW_METHOD(setm);
    _OBJ_NEW_METHOD(rm);
    _OBJ_NEW_METHOD(mv);
    _OBJ_NEW_METHOD(save);
    _OBJ_NEW_METHOD(nmatch);
    _OBJ_NEW_METHOD(insert);
    _OBJ_NEW_METHOD(error);

    Local<Object> O = tpl->NewInstance();
    obj->Wrap(O);
    return O;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Update: object tenplate may be created once, also FunctionTemplate may be reused.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.