一、在C代码中调用JS的函数
Emscripten提供了多种在C环境中调用JS函数的方法:①EM_JS ②EM_ASM宏内联JS代码 ③emscripten_run_scripten()函数 ④JS函数注入C环境
1.1 C函数声明
在C环境中,存在模块A中创建函数声明,在模块B中实现函数体。在Emscripten中,C代码部分就是模块A,js代码部分就是模块B。
EM_PORT_API(void) js_console_log_int(int param);
EM_PORT_API(void) js_send_message(char* message);
EM_PORT_API(void) print_the_answer(){
js_send_message((char*)"1111111111111111111111111111111");
js_console_log_int(5);
}
其中print_the_answer调用了js_send_message发送字符串,调用js_console_log_int打印出数字5,这两个函数只是在C环境中声明,函数的实现是在JS中完成的。
1.2 JS实现C函数
在JS中实现在C环境中声明的函数,该函数可以说是C函数与JS函数沟通的桥梁。
对应文档目录如下:
在C项目中创建一个JS源文件,然后按照两个C函数各自声明定义了两个对象js_send_message和js_send_errorInfo,并将其合并到LibraryManager.library中(LibraryManager.library可以简单的理解为JS注入C环境的库):
mergeInto(LibraryManager.library,{
js_send_message:function(sendDataP, length, macAddress)
{
console.log(`js_send_message被调用了,参数为${message}`)
},
js_send_errorInfo:function(cmdId, tag, content, macAddress)
{
console.log(`js_send_errorInfo`)
}
})
执行如下编译指令:
emcc -O3 hello.cpp -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" --js-library pkg.js -o hello.js
在编译过程中需加入-s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']"
显示导出ccall和cwrap辅助函数,在微信小程序开发中才可准确调用到在c函数中定义的EM_PORT_API声明的函数。
命令执行后得到如下的目录结构,即新增了hello.wasm和hello.js文件
然后将hello.js和hello.wasm导入微信小程序项目中,微信小程序project目录如下:
1.3 微信小程序中实现与C函数的交互
导入以上编译好的hello.js和hello.wasm文件后,在hello.js中加入以下导出代码,方便使用该js下的方法。
module.exports = {
Module: Module
}
假设在c函数中处理好的数据后要发送至微信小程序使用,则可以在c项目中定义函数
EM_PORT_API(void)
js_send_message(void *sendDataP, uint32_t length, const char *macAddress);
然后在pkg.js文件中实现JS实现C函数中代码
mergeInto(LibraryManager.library,{
js_send_message:function(sendDataP, length, macAddress)
{
console.log(`js_send_message被调用了,参数为${message}`)
}
})
最后执行命令后生成的hello.js和hello.wasm文件导入微信小程序project中,在hello.js文件中在js_send_message中的参数便是需要交互的数据,可在该函数中处理这些参数供微信小程序其他页面开发显示等操作使用。
比如声明一个在hello.js声明一个函数,或者一个全局变量,通过导出Module在其他文件中import引入后调用该方法获取该参数。
使用该方法的原因是由于2023年微信小程序还没有实现WebAssembly.Module 这个标准接口,无法像html等那样直接使用,只能通过在微信小程序中的方法中实现后再导出给到其他文件下使用。
1.4 字符串
C中字符串表达方式与JS完全不兼容,Emscripten提供一组辅助函数用于交换
- UTF8ToString():该函数可以将C的字符串转换为JS字符串
- allocateUTF8():该函数将C内存中分配足够大的空间,并将字符串按UTF8格式复制到分配的内存中。