当js module

时间:2017-03-09 16:08:57

标签: node.js duktape

在微芯片32上使用Duktape,一切运行良好。 顺便说一句,当使用模块加载(也像魅力一样工作)时,我面临着一种模式问题。 让我解释一下: 我在js模块中定义了一个构造函数

var MyObject = function(a){
this.a = a;
}
...
module.exports = MyObject;

现在我在其他程序中使用此模块。

const toto = require('myobject');
var dummy = new toto('1');

仍在工作。

问题是:如何在不知道名称(' toto ')的情况下从C调用MyObject构造函数时需要模块(基本上与用户相关)。

duk_push_global_object(ctx); // [global]
duk_bool_t res = duk_get_prop_string(ctx, -1, "toto"); // [global toto]
duk_push_string(ctx, "1"); // [global toto param0]
duk_new(ctx, 3); // [global result]
duk_remove(ctx, -2); // [result]

我要使用' MyObject '相反,没有约束,发展者声明

const MyObject = require('myobject');

我知道我可以完全用c来声明这个对象以避免这种情况,但也许你们中的一个人已经有了最好的做法。 它似乎也表明duktape不会像nodejs那样将全局范围的访问权限定义到模块中。 (我也可以将它添加到duk_module_node.c,但最后解决方案..)

感谢您的评论。

1 个答案:

答案 0 :(得分:0)

尝试不同的模式后,我认为最直接的解决方案是添加一个全球性的模式。参数作为模块包装器(类似于nodejs)。 这里是duk_module_node.c中的小代码修改

#ifdef ADD_GLOBAL_TO_MODULES
    duk_push_string(ctx, "(function(exports,require,module,__filename,__dirname,global){");
#else
    duk_push_string(ctx, "(function(exports,require,module,__filename,__dirname){");
#endif // ADD_GLOBAL_TO_MODULES

    duk_dup(ctx, -2);  /* source */
    duk_push_string(ctx, "})");
    duk_concat(ctx, 3);

    /* [ ... module source func_src ] */

    (void) duk_get_prop_string(ctx, -3, "filename");
    duk_compile(ctx, DUK_COMPILE_EVAL);
    duk_call(ctx, 0);

    /* [ ... module source func ] */

    /* Set name for the wrapper function. */
    duk_push_string(ctx, "name");
    duk_push_string(ctx, "main");
    duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);

    /* call the function wrapper */
    (void) duk_get_prop_string(ctx, -3, "exports");   /* exports */
    (void) duk_get_prop_string(ctx, -4, "require");   /* require */
    duk_dup(ctx, -5);                                 /* module */
    (void) duk_get_prop_string(ctx, -6, "filename");  /* __filename */
    duk_push_undefined(ctx);                          /* __dirname */
#ifdef ADD_GLOBAL_TO_MODULES
    duk_push_global_object(ctx);                      /* global */
    duk_call(ctx, 6);
#else
    duk_call(ctx, 5);
#endif 

将ADD_GLOBAL_TO_MODULES定义为duk_module_node.h

#define ADD_GLOBAL_TO_MODULES

现在可以通过以下方式在模块中使用js代码:

var _static = function (value, timestamp, quality, index) {
    this.value = value;
    this.timestamp = timestamp || new Date().getTime();
    this.quality = quality || _static.Quality.GOOD;
    this.index = index || _static.INDEX_NONE;
}

_static.Quality = { GOOD: 0, UNCERTAIN: 1, BAD: 2, UNKNOWN: 3 };
_static.INDEX_NONE = -1;

_static.prototype = (function () {
    var _proto = _static.prototype;
    return _proto;
})();

module.exports = _static ;
if(global) global.DatapointSample = global.DatapointSample || _static ;

您现在可以使用

new DataPointSample()

在任何地方或者从知道名字的地方打电话给它。

我知道这有必要保持c和js在微控制器固件中命名为BUT,这是非常可接受的。

问候。