最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does `require` cause an error in Duktape? - Stack Overflow

programmeradmin2浏览0评论

I am using Duktape to embed JavaScript, but using require always causes an error:

int main(){
  duk_context *ctx = duk_create_heap_default();
  duk_peval_file(ctx, "example.js");
  printf("file load err %s", duk_safe_to_string(ctx, -1));
  duk_destroy_heap(ctx);
}

example.js

var mylib = require("mylib")
print (mylib.hello)

mylib.js

exports.hello = "Hello"

Error:

file load err TypeError: not callable

Stack dump says:

duk_js_call.c:682
require native strict preventsyield
eval example.js:1 preventsyield

I am using Duktape to embed JavaScript, but using require always causes an error:

int main(){
  duk_context *ctx = duk_create_heap_default();
  duk_peval_file(ctx, "example.js");
  printf("file load err %s", duk_safe_to_string(ctx, -1));
  duk_destroy_heap(ctx);
}

example.js

var mylib = require("mylib")
print (mylib.hello)

mylib.js

exports.hello = "Hello"

Error:

file load err TypeError: not callable

Stack dump says:

duk_js_call.c:682
require native strict preventsyield
eval example.js:1 preventsyield

Share Improve this question edited May 29, 2017 at 18:07 Badacadabra 8,5357 gold badges31 silver badges54 bronze badges asked Feb 25, 2015 at 21:21 caydanlikcaydanlik 513 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Duktape requires (no pun intended) you to provide a Module Search function in order to preserve portability. However, implementing one is a pretty simple and straight-forward task even if you have little experience in Duktape.
A very simple but fully functional Module Search function would be:

Duktape.modSearch = function(id) {
    return readFileAsString(id);
}

This would allow you to call require(filename) from the Duktape Javascript environment with a filename as parameter and use it as your module. A more advanced function would handle errors or maybe search multiple paths and folders.

To use the require() function, you now have to create a C/C++ function that handles reading a file and returning it's content as a string and bind this function to the Duktape engine (Example for this is on the Duktape home page).
Now call this function definition from the Duktape runtime (For example using duk_eval_string(ctx, "Duktape.modSearch = ...");) and you should be able to call require().

This answer is fairly inplete. Leave many things to the imagination.

The following code is not mine, but is also available in sof and solves the problem of implementing the modSearch function:

duk_ret_t mod_search(duk_context *ctx) {
    /* Nargs was given as 4 and we get the following stack arguments:
     *   index 0: id
     *   index 1: require
     *   index 2: exports
     *   index 3: module
     */
char *src = NULL;
FILE *f   = NULL;
const char *filename = "/home/user/benchmark/js_modules/mylib.js";

int  rc, len;

// Pull Arguments
char *id = duk_require_string(ctx, 0);

printf("ID => %s \n", id);

rc = strcmp(id, "mylib");
if(rc == 0)
{
    printf("Module found, loading... \n");
    // Read File and calculate its size (as DUKtape examples)
    f = fopen(filename, "rb");
    fseek(f, 0, SEEK_END);
    len = (int) ftell(f);

    // Rewind
    fseek(f, 0, SEEK_SET);

    src = malloc(len);
    fread(src, 1, len,f);
    fclose(f);
    duk_push_lstring(ctx, src, len);
    free(src);
    return 1;
  }
// Error
    return -1;
}

Then, we need a native-code C function to register the modSearch function:

/* Declaration */
void modSearch_register(duk_context *ctx) {
    duk_get_global_string(ctx, "Duktape");
    duk_push_c_function(ctx, mod_search, 4 /*nargs*/);
    duk_put_prop_string(ctx, -2, "modSearch");
    duk_pop(ctx);
}

Then the main code:

duk_context *ctx;

ctx = duk_create_heap_default();
if (!ctx) {
    return 1;
}
duk_push_c_function(ctx, handle_print, 1);
duk_put_global_string(ctx, "print");
duk_module_duktape_init(ctx);
printf("top after init: %ld\n", (long) duk_get_top(ctx));
//call function defintion for require
modSearch_register(ctx);

/* We push to Duktape heap the JS file*/
push_file_as_string(ctx, argv[1]);
if (duk_peval(ctx) != 0) {
    printf("Error peval: %s\n", duk_safe_to_string(ctx, -1));
        goto finished;
    }
duk_pop(ctx);  /* pop result/error */

finished:
duk_destroy_heap(ctx);

The native c code print function can be obtained from duktape web page, for example:

static duk_ret_t handle_print(duk_context *ctx) {
    printf("%s\n", duk_safe_to_string(ctx, 0));
    return 0;
}
发布评论

评论列表(0)

  1. 暂无评论