1. 使用编译命令就可以将.cpp文件编译为.html文件,并在网页进行运行:
./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS="['_int_sqrt']"
2. ①编译完,你可以使用JavaScript调用cwrap()拿到int_sqrt函数。继而可以进行其他操作。
int_sqrt = Module.cwrap('int_sqrt', 'number', ['number'])
int_sqrt(12)
int_sqrt(28)
第一个参数是函数名,第二个参数是函数返回类型,第三个是参数类型。
返回类型和参数类型中可以用类型有三个,分别是number,string和array。number(是js中的number,对应着C中的整型,浮点型,一般指针),string(是JavaScript中的string,对应着C中的char,C中char表示一个字符串),array(是js中的数组或类型数组,对应C中的数组;如果是类型数组,必须为Uint8Array或者Int8Array)。
② 使用.cwrap()的注意事项
- 这些方法用于编译的C函数,对进行过函数名改编的C++函数不工作。
- 推荐你导出你要用JavaScript调用的函数。
A. 导出是在编译阶段做的。比如-s EXPORTED_FUNCTIONS='["_main","_other_function"]' 导出了main()和other_function()。
B. 导出时给函数名加下划线“_”,见A。
C. A中把main也导出了,如果你不导出main,mian就会变成无效代码,这个导出列表应该是完整 的可以keep alive的函数列表。
D. Emscripten会做无效代码清除以减小生成的代码体积,所以请确保导出了所有你想用js调的函数。
E. 如果编译是优化编译-O2级别及以上,会进行代码改编,包括函数名。但是通过-s EXPORTED_FUNCTIONS导出的函数可以继续使用原来的函数名。
F. 如果你想导出一个js库函数(比如,src/library*.js这样的),除了用EXPORTED_FUNCTIONS ,还得用DEFAULT_LIBRARY_FUNCS_TO_INCLUDE。 * 使用Module.ccall调用,不要直接用ccall。前者在代码进行优化编译时也工作。
3. 在JS中直接调C中的函数,不必使用ccall()或cwrap()
①使用编译命令:
emcc api_example.c -o api_example.js
②可以用以下代码执行这个库中的函数:
var em_module = require('./api_example.js');
em_module._sayHi(); // 方法一:直接调用,函数名前要加_
em_module.ccall("sayHi"); // 方法二:使用ccall或cwrap调用,函数名前不需要加_