emscripten_run_script
2.5介绍的EM_ASM系列宏只能接受硬编码常量字符串,而本节将要介绍的emscripten_run_script系列函数可以接受动态输入的字符串,该系列辅助函数可以类比于JavaScript中的eval()方法。
EM_ASM
eval()
emscripten_run_script()
函数声明:
void emscripten_run_script(const char *script)
参数:
script
返回值:
函数使用很简单,例如:
int main(){ emscripten_run_script("console.log(42);"); return 0; }
上述代码中emscripten_run_script("console.log(42);");执行效果等价于在JavaScript中执行console.log(42);。
emscripten_run_script("console.log(42);");
console.log(42);
emscripten_run_script()可以接受动态生成的字符串,例如:
const char* get_js_code(){ static char buf[1024]; sprintf(buf, "console.log('你好,Emscripten!');"); return buf; } int main(){ emscripten_run_script(get_js_code()); return 0; }
由于传入的脚本最终会通过JavaScript的eval()方法执行,因此传入的脚本可以是任意的JavaScript代码,比如:
emscripten_run_script(R"( function my_print(s) { console.log("JS:my_print():", s); } my_print("Hello!"); )");
上述代码先定义了一个方法my_print(),然后调用它输出了“Hello!”
my_print()
tips 为了避免使用转义符方便阅读,上述例子定义字符串时,使用了C++11标准的raw字符串定义方法(R前缀),在使用emcc命令编译时,必须增加-std=c++11参数,完整的命令行为: emcc emscripten_run_script.cc -std=c++11 -o emscripten_run_script.js
tips 为了避免使用转义符方便阅读,上述例子定义字符串时,使用了C++11标准的raw字符串定义方法(R前缀),在使用emcc命令编译时,必须增加-std=c++11参数,完整的命令行为:
R
emcc
-std=c++11
emcc emscripten_run_script.cc -std=c++11 -o emscripten_run_script.js
emscripten_run_script_int()
int emscripten_run_script_int(const char *script)
该函数与emscripten_run_script()类似,区别是它会将输入的脚本的执行结果作为整型数返回,例如:
int num = emscripten_run_script_int(R"( function show_me_the_number() { return 13; } show_me_the_number(); )"); printf("num:%d\n", num);
上述程序将输出:
num:13
emscripten_run_script_string()
char *emscripten_run_script_string(const char *script)
该函数与emscripten_run_script_int()类似,区别是返回值为字符串,例如:
const char* str = emscripten_run_script_string(R"( function show_me_the_answer() { return "The answer is 42."; } show_me_the_answer(); )"); printf("%s\n", str);
The answer is 42.
我们在胶水代码中可以看到辅助函数emscripten_run_script_string()实现代码如下:
function _emscripten_run_script_string(ptr) { var s = eval(Pointer_stringify(ptr)) + ''; var me = _emscripten_run_script_string; var len = lengthBytesUTF8(s); if (!me.bufferSize || me.bufferSize < len+1) { if (me.bufferSize) _free(me.buffer); me.bufferSize = len+1; me.buffer = _malloc(me.bufferSize); } stringToUTF8(s, me.buffer, me.bufferSize); return me.buffer; }
该函数在C/C++内存中分配了空间,用于保存传入脚本执行后返回的字符串。并且从代码中不难发现,多次调用emscripten_run_script_string()时,后面调用的结果有可能覆盖前面调用的结果——因为me.buffer是重复使用的。
me.buffer
本节例子的输出如下:
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8