将duktape 2.1.0中的本地C模块加载到

在阅读how-to文章后,我仍然迷失了方向。

  • https://github.com/svaarala/duktape/tree/master/extras/module-node

据说

负载callback函数是一个Duktape / C函数,它使用已parsing的模块ID,并且:(1)返回模块的Ecmascript源代码,或者如果没有源代码,则返回undefined,例如纯C模块;(2)可以填充module.exports本身,(3)可以取代module.exports。

但是当加载一个本地C模块时,

  • 什么应该推入价值栈? duk_push_undefined(ctx)而不是duk_push_string(ctx, module_source)
  • 负载callback应该返回给调用者的是什么? return 0而不是return 1

我试图在loadcallbackcb_load_module调用myobject_init (使用http://wiki.duktape.org/HowtoNativeConstructor.html中的默认实例)。 但是duktape抱怨

TypeError:[对象对象]不可构造

当我评估var MyObject = require("MyObject") ,无论如何

  • 将undefined push到值栈中并返回1,
  • 或者将任何东西压入值栈并返回0。

问题解决了。 还有更多的细节散落在其中

最重要的技巧是:

  • 模块init函数应该返回一个函数(构造函数也是一个函数)。 不要使用duk_put_global_string注册函数。

     duk_ret_t module_init(duk_context* ctx) { duk_push_c_function(ctx, module_constructor, num_arguments_for_constructor); // set properties for the constructor return 1; // stack: [ ... constructor ] } 
  • 函数cb_load_module必须将模块初始化函数推入值栈,然后使用duk_call调用它并设置module.exports 。 不要直接调用模块初始化函数。

     duk_ret_t cb_load_module(duk_context *ctx) { // stack: [ resolved_id exports module ] ... duk_push_c_function(ctx, module_init, 0); duk_call(ctx, 0); duk_put_prop_string(ctx, 2, "exports"); // obj_idx(module) = 2 return 0; // no .js source for native modules }