2017-03-09 129 views
1

在microchip 32上使用Duktape,一切运行良好。 顺便说一句,当使用模块加载(这也是一种魅力),我正面临着一种模式问题。 让我解释道: 我定义一个js模块当在js模块中定义对象构造函数时,从C调用JS对象构造函数

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

内部构造现在,我使用anothers程序里面这个模块。

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”,而不是无约束的developper申报

const MyObject = require('myobject'); 

我知道我可以在C完全申报对象,以避免这种情况,但也许你们中的一个具有已经是最佳实践了。 duktape似乎也没有像nodejs那样将全局范围的访问定义为模块。 (我也可以添加到duk_module_node.c,但最后的解决方案..)

感谢您的意见。

回答

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都命名,但在微控制器固件中它是非常可以接受的。

问候。