为什么`require`会导致Duktape出错?

时间:2015-02-25 21:21:43

标签: javascript duktape

我正在使用Duktape嵌入JavaScript,但使用require始终会导致错误:

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"

错误:

  

file load err TypeError:not callable

堆栈转储说:

  

duk_js_call.c:682个
  要求原生严格的要求   eval example.js:1 preventyield

2 个答案:

答案 0 :(得分:4)

Duktape要求(没有双关语)你提供Module Search function以保持可移植性。然而,即使您对Duktape缺乏经验,实施一个也是一项非常简单和直接的任务 一个非常简单但功能齐全的模块搜索功能是:

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

这将允许您使用 filename 作为参数从Duktape Javascript环境中调用require(filename)并将其用作您的模块。更高级的功能可以处理错误或搜索多个路径和文件夹。

要使用require()函数,您现在必须创建一个C / C ++函数来处理读取文件并将其作为字符串返回并将此函数绑定到Duktape引擎(示例为这是在Duktape主页上 现在从Duktape运行时调用此函数定义(例如使用duk_eval_string(ctx, "Duktape.modSearch = ...");),您应该能够调用require()

答案 1 :(得分:0)

这个答案还很不完整。让很多事情浮想联翩。

以下代码不是我的,但也可以在sof中使用,并解决了实现modSearch函数的问题:

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;
}

然后,我们需要一个本机代码C函数来注册modSearch函数:

/* 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);
}

然后输入主要代码:

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);

本地c代码打印功能可以从duktape网页获得,例如:

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