1

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

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

现在我在另一个程序中使用这个模块。

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

还在工作。

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

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,但最终解决方案..)

感谢您的意见。

4

1 回答 1

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 中调用它。

我知道有义务在微控制器固件中同时维护 c 和 js 命名,但这是可以接受的。

问候。

于 2017-03-09T18:19:37.683 回答