admin管理员组文章数量:1025478
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:
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 badgesduk_js_call.c:682
require native strict preventsyield
eval example.js:1 preventsyield
2 Answers
Reset to default 6Duktape 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;
}
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:
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 badgesduk_js_call.c:682
require native strict preventsyield
eval example.js:1 preventsyield
2 Answers
Reset to default 6Duktape 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;
}
本文标签: javascriptWhy does require cause an error in DuktapeStack Overflow
版权声明:本文标题:javascript - Why does `require` cause an error in Duktape? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745623417a2159713.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论