我正在使用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
答案 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;
}